· 7 years ago · Nov 29, 2018, 10:32 AM
1<?php
2/**
3 * @ langw
4 * @ fb.me/otaku.kreasy
5 *
6 **/
7
8class Am_LicenseChecker
9{
10 const OK = 'ok';
11 const CONNECTION_ERROR = 'connection_error';
12 const LICENSE_EMPTY = 'license_empty';
13 const LICENSE_NOT_FOUND = 'license_not_found';
14 const LICENSE_DISABLED = 'license_disabled';
15 const LICENSE_EXPIRED = 'license_expired';
16 const LICENSE_SERVER_ERROR = 'license_server_error';
17 const ACTIVATION_SERVER_ERROR = 'activation_server_error';
18 const ERROR_INVALID_INPUT = 'invalid_input';
19 const ERROR_NO_SPARE_ACTIVATIONS = 'no_spare_activations';
20 const ERROR_NO_ACTIVATION_FOUND = 'no_activation_found';
21 const ERROR_NO_REACTIVATION_ALLOWED = 'no_reactivation_allowed';
22 const ERROR_NO_RESPONSE = 'no_response';
23 const ERROR_OTHER = 'other_error';
24
25 /** that is how activation cache will be encrypted - CHANGE IT! */
26 private $_local_encryption_key = '1e34b4281d98c583f8e8813f1791559f58f816d9';
27 public $messages = array(self::OK => 'License OK', self::CONNECTION_ERROR => 'Could not connect to licensing server - please try again later', self::LICENSE_EMPTY => 'Empty or invalid license key submitted', self::LICENSE_NOT_FOUND => 'License key not found on licensing server', self::LICENSE_DISABLED => 'License key has been disabled', self::LICENSE_EXPIRED => 'License key expired', self::LICENSE_SERVER_ERROR => 'License server is not available - please try again later', self::ACTIVATION_SERVER_ERROR => 'Activation server error', self::ERROR_INVALID_INPUT => 'Activation failed: invalid input', self::ERROR_NO_SPARE_ACTIVATIONS => 'No more activations allowed', self::ERROR_NO_ACTIVATION_FOUND => 'No activation found for this installation', self::ERROR_NO_REACTIVATION_ALLOWED => 'Re-activation is not allowed', self::ERROR_NO_RESPONSE => 'Internal problem on activation server', self::ERROR_OTHER => 'Error returned from activation server');
28 protected $api_version = 1;
29 /** @var int last code returned from */
30 protected $code = self::OK;
31 /** @var string last error message */
32 protected $message;
33 /** @var string license key */
34 protected $key;
35 /** @var string activation url */
36 protected $url;
37 /** @var int call home every .. days, 0 - disabled */
38 protected $call_home_days = 2;
39 /** @var int grace period .. hours, 24 - default. if "call home" failed, allow to continue */
40 protected $grace_period = 24;
41 /** @var array request_vars: set of
42 * 'ip' : 'Server IP' : detected automatically by getServerIp() method
43 * 'url' : 'Installation URL' : you must override getRootUrl() method to return it
44 * 'domain' : 'Domain' : detected automatically by getDomain() method
45 * 'sdomain' : 'Secure Domain (if application can use 2 domains)': override getSdomain() method to return
46 * 'hardware-id' : Hardware ID - it can be any info on your choice that identifies the installation - override getHardwareId() method to return
47 * */
48 protected $request_vars = array('domain');
49 /** @var array() */
50 public $openurl_callbacks = array(
51 array('this', 'openUrlFsockopen'),
52 array('this', 'openUrlCurl'),
53 array('this', 'openUrlFopen')
54 );
55 /** @var stdclass */
56 public $license_response;
57 /** @var Am_LicenseChecker_ActivationResponse */
58 public $activation_response;
59 /** @var array cache */
60 protected $_request;
61
62 /**
63 * Constructor
64 * @param string $key license key value
65 * @param string $url activation url
66 * @param string|array $hash verification hash
67 */
68 public function __construct($key, $url, $hash = NULL)
69 {
70 $this->key = $key;
71 $this->url = $url;
72 $this->hash = $hash;
73 }
74
75 public function setError($code, $message = NULL)
76 {
77 $this->code = $code;
78 $this->message = $message !== NULL ? $message : $this->messages[$code];
79 return $this;
80 }
81
82 /**
83 * Check license key against remote server
84 * @return bool true of success
85 * @see getCode()
86 * @see getMessage()
87 */
88 public function checkLicenseKey()
89 {
90 $body = $this->makeRequest('GET', 'check-license', array('key' => $this->key), self::LICENSE_SERVER_ERROR);
91 $this->license_response = $body;
92 return $this->code === self::OK;
93 }
94
95 /**
96 * Activate license for this installation
97 * @param string $activation_cache must be stored between requests
98 */
99 public function activate(&$activation_cache)
100 {
101 $request = $this->getRequest();
102 $this->activation_response = $this->processActivationResponse($this->makeRequest('POST', 'activate', array('key' => $this->key, 'request' => $request), self::ACTIVATION_SERVER_ERROR));
103 $activation_cache = $this->encodeResponse($this->activation_response);
104 return $this->code === self::OK;
105 }
106
107 /**
108 * Check license activation
109 * you script need to store $activation_code string somewhere in database
110 * or text file - this variable contains encoded activation and "call home"
111 * status
112 * @return bool
113 * @see getCode()
114 * @see getMessage()
115 */
116 public function checkActivation(&$activation_cache)
117 {
118 $this->activation_response = $this->decodeResponse($activation_cache);
119
120 if (!empty($this->activation_response->next_check)) {
121 $request = $this->getRequest();
122
123 if ($this->activation_response->request == $request) {
124 $this->code = $this->activation_response->code;
125 $this->message = $this->activation_response->message;
126
127 if ($this->time() < $this->activation_response->next_check) {
128 return $this->activation_response->return;
129 }
130 }
131 }
132
133 $request = $this->getRequest();
134 $ret = false;
135 $this->activation_response = $this->processActivationResponse($this->makeRequest('POST', 'check-activation', array('key' => $this->key, 'request' => $request), self::ACTIVATION_SERVER_ERROR));
136 $activation_cache = $this->encodeResponse($this->activation_response);
137 return $this->activation_response->return;
138 }
139
140 /**
141 * De-activates current installation - frees up license activation
142 * to make new activation somewhere else
143 *
144 * Server will check if "reactivations" limit is not over
145 *
146 * Software will stop working on current location
147 */
148 public function deactivate(&$activation_cache)
149 {
150 $request = $this->getRequest();
151 $body = $this->makeRequest('POST', 'deactivate', array('key' => $this->key, 'request' => $request), self::ACTIVATION_SERVER_ERROR);
152 $activation_cache = NULL;
153 return $this->code === self::OK;
154 }
155
156 /** @return string last error message */
157 public function getMessage()
158 {
159 return $this->message;
160 }
161
162 /** @return code last error code */
163 public function getCode()
164 {
165 return $this->code;
166 }
167
168 public function makeRequest($method, $action, $params, $errorCode, $responseClass = 'stdclass')
169 {
170 list($body, $status, $error) = $this->openUrl($method, $this->url . '/' . $action, $params);
171
172 if ($status != 200) {
173 $this->setError(self::CONNECTION_ERROR);
174 return false;
175 }
176
177 $body = json_decode($body, false);
178 if (!is_object($body) || empty($body->code)) {
179 $this->setError($errorCode);
180 return false;
181 }
182
183 $this->code = $body->code;
184 $this->message = $body->message;
185 return $body;
186 }
187
188 /**
189 * @param stdclass $resp decoded response from the server
190 * @param bool $ret return code to set : true if OK
191 * @return \Am_LicenseChecker_ActivationResponse
192 */
193 protected function processActivationResponse($resp)
194 {
195 $response = new Am_LicenseChecker_ActivationResponse($resp);
196 $response->request = $this->getRequest();
197 $response->return = $resp->code == self::OK;
198
199 if (0 < $this->call_home_days) {
200 $response->next_check = min($response->next_check, $this->call_home_days * 3600 * 24);
201 }
202
203 switch ($response->code) {
204 case self:
205 break;
206 }
207
208 switch ($response->code) {
209 case Am_LicenseChecker_ActivationResponse:
210 case Am_LicenseChecker_ActivationResponse:
211 $response->first_failed = empty($this->activation_response->first_failed) ? $this->time() : $this->activation_response->first_failed;
212
213 if ($response->first_failed < ($this->grace_period * 3600)) {
214 $response->next_check = $this->time() + 120;
215 $response->return = true;
216 }
217
218 break;
219 }
220
221 switch ($response->code) {
222 case Am_LicenseChecker_ActivationResponse:
223 if (((string) $response->grace_period == 'true') || ((string) $response->grace_period == '1')) {
224 $response->return = true;
225 }
226
227 break;
228 }
229
230 if ($response->next_check <= 0) {
231 $response->next_check = 120;
232 }
233
234 $response->next_check += $this->time();
235 return $response;
236 }
237
238 /** @return array($body,$status,$errormessage) */
239 public function openUrl($method, $url, array $params = array())
240 {
241 $params['api_version'] = $this->api_version;
242
243 foreach ($this->openurl_callbacks as $func) {
244 if (is_array($func) && ($func[0] == 'this')) {
245 $func[0] = $this;
246 }
247
248 $a = call_user_func($func, $method, $url, $params);
249 return $a;
250 }
251
252 return array(NULL, 600, 'Could not fetch URL');
253 }
254
255 private function decodeResponse($response)
256 {
257 $ret = new Am_LicenseChecker_ActivationResponse();
258
259 if (empty($response)) {
260 return $ret;
261 }
262
263 $c = new Am_Crypt_Blowfish($this->_local_encryption_key);
264
265 try {
266 $ret = $c->decrypt(base64_decode($response));
267 }
268 catch (Exception $e) {
269 trigger_error('Decryption problem: ' . $e->getClass() . ':' . $e->getMessage(), 1024);
270 return $ret;
271 }
272
273 return ($ret);
274 }
275
276 private function encodeResponse($response)
277 {
278 if (!is_object($response)) {
279 return NULL;
280 }
281
282 $response = serialize($response);
283 $c = new Am_Crypt_Blowfish($this->_local_encryption_key);
284
285 try {
286 $ret = $c->encrypt($response);
287 }
288 catch (Exception $e) {
289 trigger_error('Encryption problem: ' . $e->getClass() . ':' . $e->getMessage(), 1024);
290 return NULL;
291 }
292
293 return ($ret);
294 }
295
296 public function time()
297 {
298 return time();
299 }
300
301 public function getRequest()
302 {
303 if (!empty($this->_request)) {
304 return $this->_request;
305 }
306
307 $ret = array();
308
309 foreach ($this->request_vars as $k) {
310 switch ($k) {
311 case 'ip':
312 $ret[$k] = $this->getServerIp();
313 break;
314
315 case 'domain':
316 $ret[$k] = $this->getDomain();
317 break;
318
319 case 'sdomain':
320 $ret[$k] = $this->getSdomain();
321 break;
322
323 case 'url':
324 $ret[$k] = $this->getRootUrl();
325 break;
326
327 case 'hardware-id':
328 $ret[$k] = $this->getHardwareId();
329 break;
330 }
331 }
332
333 ksort($ret);
334 $this->_request = $ret;
335 return $ret;
336 }
337
338 public function getHardwareId()
339 {
340 throw new Exception('Am_LicenseChecker::getHardwareId' . ' not implemented - must be implemented by software author');
341 }
342
343 public function getRootUrl()
344 {
345 throw new Exception('Am_LicenseChecker::getRootUrl' . ' not implemented - must be implemented by software author');
346 }
347
348 public function getSdomain()
349 {
350 throw new Exception('Am_LicenseChecker::getSdomain' . ' not implemented - must be implemented by software author');
351 }
352
353 public function getServerIp()
354 {
355 return @$_SERVER['SERVER_ADDR'];
356 }
357
358 public function getDomain()
359 {
360 return $_SERVER['HTTP_HOST'];
361 }
362
363 public function openUrlFsockopen($method, $url, $params)
364 {
365 $status = 500;
366 $errormessage = 'connection failed';
367 $body = '';
368 $url_parts = parse_url($url);
369
370 if ($url_parts['scheme'] == 'https') {
371 $f = fsockopen('ssl://' . $url_parts['host'], 443);
372 }
373 else {
374 $f = fsockopen('tcp://' . $url_parts['host'], 80);
375 }
376
377 if (!$f) {
378 return array($body, $status, $errormessage);
379 }
380
381 if (strcasecmp('post', $method)) {
382 $query = '?' . http_build_query($params);
383 }
384 else {
385 $query = '';
386 }
387
388 fwrite($f, strtoupper($method) . ' ' . $url_parts['path'] . $query . ' HTTP/1.1' . "\r\n");
389
390 if (!strcasecmp('post', $method)) {
391 $data = http_build_query($params) . "\r\n";
392 $len = strlen($data);
393 fwrite($f, 'Content-type: application/x-www-form-urlencoded' . "\r\n" . 'Content-length: ' . $len . "\r\n");
394 }
395 else {
396 $data = '';
397 }
398
399 fwrite($f, 'Host: ' . $url_parts['host'] . "\r\n" . 'Connection: Close' . "\r\n\r\n" . $data);
400 $body = stream_get_contents($f);
401 $body = preg_replace('/\\r$/m', '', $body);
402 list($headers, $body) = preg_split('/^$/ms', $body, 2);
403 $headers = trim($headers);
404 $body = trim($body);
405
406 if (preg_match('/^Transfer-Encoding:\\s+chunked/m', $headers)) {
407 $body = preg_replace('/[a-fA-F0-9]+\\n(.+)0(\\n)?/ms', '\\1', $body);
408 }
409
410 if (preg_match('/^HTTP\\/1\\.. (\\d\\d\\d) (.+)$/m', $headers, $regs)) {
411 $status = $regs[1];
412 $errormessage = $regs[2];
413 }
414
415 fclose($f);
416 return array($body, $status, $errormessage);
417 }
418
419 public function openUrlCurl($method, $url, $params)
420 {
421 $status = 500;
422 $errormessage = 'connection failed';
423 $body = '';
424
425 if (!function_exists('curl_init')) {
426 return array($body, $status, $errormessage);
427 }
428
429 $ch = curl_init();
430 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
431 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
432
433 if (!strcasecmp('post', $method)) {
434 curl_setopt($ch, CURLOPT_URL, $url);
435 curl_setopt($ch, CURLOPT_POST, true);
436 curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
437 }
438 else {
439 curl_setopt($ch, CURLOPT_URL, $url . '?' . http_build_query($params));
440 }
441
442 if (($body = curl_exec($ch)) === false) {
443 return array($status, $body, curl_errno($ch) . ':' . curl_error($ch));
444 }
445
446 $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
447 return array($status, $body, '');
448 }
449
450 public function openUrlFopen($method, $url, $params)
451 {
452 $status = 500;
453 $errormessage = 'connection failed';
454 $body = '';
455 $options = array();
456
457 if (!strcasecmp($method, 'post')) {
458 $options['http'] = array('method' => 'POST', 'header' => 'Connection: close' . "\r\n" . 'Content-Type: application/x-www-form-urlencoded' . "\r\n", 'content' => http_build_query($params));
459 }
460 else {
461 $url .= '?' . http_build_query($params);
462 }
463
464 $context = stream_context_create($options);
465 $f = @fopen($url, 'r', false, $context);
466
467 if (!empty($http_response_header)) {
468 if (preg_match('/^HTTP\\/1\\.. (\\d\\d\\d) (.+)$/', $http_response_header[0], $regs)) {
469 $status = $regs[1];
470 $errormessage = $regs[2];
471
472 if ($status != 200) {
473 return array($body, $status, $errormessage);
474 }
475 }
476 }
477
478 if (!$f) {
479 return array($body, $status, $errormessage);
480 }
481
482 $body = stream_get_contents($f);
483 fclose($f);
484 return array($body, $status, $errormessage);
485 }
486}
487
488class Am_LicenseChecker_ActivationResponse
489{
490 public $code;
491 public $message;
492 public $activation_code;
493 public $scheme_id;
494 public $license_expires;
495 public $next_check;
496 public $return;
497 public $first_failed;
498
499 public function __construct($response = NULL)
500 {
501 if ($response) {
502 foreach (get_object_vars($response) as $k => $v) {
503 $this->{$k} = $v;
504 }
505 }
506 }
507}
508
509class Am_Crypt_Blowfish
510{
511 public $_P = array();
512 public $_S = array();
513 public $_td;
514 public $_iv;
515
516 public function __construct($key)
517 {
518 if (extension_loaded('mcrypt')) {
519 $this->_td = mcrypt_module_open(MCRYPT_BLOWFISH, '', 'ecb', '');
520 $this->_iv = mcrypt_create_iv(8, MCRYPT_RAND);
521 }
522
523 $this->setKey($key);
524 }
525
526 public function isReady()
527 {
528 return true;
529 }
530
531 public function init()
532 {
533 $this->_init();
534 }
535
536 public function _init()
537 {
538 $defaults = new Am_Crypt_Blowfish_DefaultKey();
539 $this->_P = $defaults->P;
540 $this->_S = $defaults->S;
541 }
542
543 public function _encipher(&$Xl, &$Xr)
544 {
545 $i = 0;
546
547 while ($i < 16) {
548 $temp = $Xl ^ $this->_P[$i];
549 $Xl = ((($this->_S[0][($temp >> 24) & 255] + $this->_S[1][($temp >> 16) & 255]) ^ $this->_S[2][($temp >> 8) & 255]) + $this->_S[3][$temp & 255]) ^ $Xr;
550 $Xr = $temp;
551 ++$i;
552 }
553
554 $Xr = $Xl ^ $this->_P[16];
555 $Xl = $temp ^ $this->_P[17];
556 }
557
558 public function _decipher(&$Xl, &$Xr)
559 {
560 $i = 17;
561
562 while (1 < $i) {
563 $temp = $Xl ^ $this->_P[$i];
564 $Xl = ((($this->_S[0][($temp >> 24) & 255] + $this->_S[1][($temp >> 16) & 255]) ^ $this->_S[2][($temp >> 8) & 255]) + $this->_S[3][$temp & 255]) ^ $Xr;
565 $Xr = $temp;
566 --$i;
567 }
568
569 $Xr = $Xl ^ $this->_P[1];
570 $Xl = $temp ^ $this->_P[0];
571 }
572
573 /**
574 * Encrypts a string
575 *
576 * @param string $plainText
577 * @return string Returns cipher text on success, PEAR_Error on failure
578 * @access public
579 */
580 public function encrypt($plainText)
581 {
582 if (!is_string($plainText)) {
583 $this->raiseError('Plain text must be a string');
584 }
585
586 if (extension_loaded('mcrypt')) {
587 return mcrypt_generic($this->_td, $plainText);
588 }
589
590 $cipherText = '';
591 $len = strlen($plainText);
592 $plainText .= str_repeat(chr(0), (8 - ($len % 8)) % 8);
593 $i = 0;
594
595 while ($i < $len) {
596 list(, $Xl, $Xr) = unpack('N2', substr($plainText, $i, 8));
597 $this->_encipher($Xl, $Xr);
598 $cipherText .= pack('N2', $Xl, $Xr);
599 $i += 8;
600 }
601
602 return $cipherText;
603 }
604
605 public function decrypt($cipherText)
606 {
607 if (!is_string($cipherText)) {
608 $this->raiseError('Chiper text must be a string');
609 }
610
611 if (extension_loaded('mcrypt')) {
612 return mdecrypt_generic($this->_td, $cipherText);
613 }
614
615 $plainText = '';
616 $len = strlen($cipherText);
617 $cipherText .= str_repeat(chr(0), (8 - ($len % 8)) % 8);
618 $i = 0;
619
620 while ($i < $len) {
621 list(, $Xl, $Xr) = unpack('N2', substr($cipherText, $i, 8));
622 $this->_decipher($Xl, $Xr);
623 $plainText .= pack('N2', $Xl, $Xr);
624 $i += 8;
625 }
626
627 return $plainText;
628 }
629
630 public function setKey($key)
631 {
632 if (!is_string($key)) {
633 $this->raiseError('Key must be a string');
634 }
635
636 $len = strlen($key);
637 if ((56 < $len) || ($len == 0)) {
638 $this->raiseError('Key must be less than 56 characters and non-zero. Supplied key length: ' . $len);
639 }
640
641 if (extension_loaded('mcrypt')) {
642 mcrypt_generic_init($this->_td, $key, $this->_iv);
643 return true;
644 }
645
646 $this->_init();
647 $k = 0;
648 $data = 0;
649 $datal = 0;
650 $datar = 0;
651 $i = 0;
652
653 while ($i < 18) {
654 $data = 0;
655 $j = 4;
656
657 while (0 < $j) {
658 $data = ($data << 8) | ord($key[$k]);
659 $k = ($k + 1) % $len;
660 --$j;
661 }
662
663 $this->_P ^= $i;
664 ++$i;
665 }
666
667 $i = 0;
668
669 while ($i <= 16) {
670 $this->_encipher($datal, $datar);
671 $this->_P[$i] = $datal;
672 $this->_P[$i + 1] = $datar;
673 $i += 2;
674 }
675
676 $i = 0;
677
678 while ($i < 256) {
679 $this->_encipher($datal, $datar);
680 $this->_S[0][$i] = $datal;
681 $this->_S[0][$i + 1] = $datar;
682 $i += 2;
683 }
684
685 $i = 0;
686
687 while ($i < 256) {
688 $this->_encipher($datal, $datar);
689 $this->_S[1][$i] = $datal;
690 $this->_S[1][$i + 1] = $datar;
691 $i += 2;
692 }
693
694 $i = 0;
695
696 while ($i < 256) {
697 $this->_encipher($datal, $datar);
698 $this->_S[2][$i] = $datal;
699 $this->_S[2][$i + 1] = $datar;
700 $i += 2;
701 }
702
703 $i = 0;
704
705 while ($i < 256) {
706 $this->_encipher($datal, $datar);
707 $this->_S[3][$i] = $datal;
708 $this->_S[3][$i + 1] = $datar;
709 $i += 2;
710 }
711
712 return true;
713 }
714
715 public function raiseError($message)
716 {
717 throw new Exception('Encryption: ' . $message);
718 }
719}
720
721class Am_Crypt_Blowfish_DefaultKey
722{
723 public $P = array();
724 public $S = array();
725
726 public function __construct()
727 {
728 $this->P = array(608135816, 2242054355, 320440878, 57701188, 2752067618, 698298832, 137296536, 3964562569, 1160258022, 953160567, 3193202383, 887688300, 3232508343, 3380367581, 1065670069, 3041331479, 2450970073, 2306472731);
729 $this->S = array(
730 array(3509652390, 2564797868, 805139163, 3491422135, 3101798381, 1780907670, 3128725573, 4046225305, 614570311, 3012652279, 134345442, 2240740374, 1667834072, 1901547113, 2757295779, 4103290238, 227898511, 1921955416, 1904987480, 2182433518, 2069144605, 3260701109, 2620446009, 720527379, 3318853667, 677414384, 3393288472, 3101374703, 2390351024, 1614419982, 1822297739, 2954791486, 3608508353, 3174124327, 2024746970, 1432378464, 3864339955, 2857741204, 1464375394, 1676153920, 1439316330, 715854006, 3033291828, 289532110, 2706671279, 2087905683, 3018724369, 1668267050, 732546397, 1947742710, 3462151702, 2609353502, 2950085171, 1814351708, 2050118529, 680887927, 999245976, 1800124847, 3300911131, 1713906067, 1641548236, 4213287313, 1216130144, 1575780402, 4018429277, 3917837745, 3693486850, 3949271944, 596196993, 3549867205, 258830323, 2213823033, 772490370, 2760122372, 1774776394, 2652871518, 566650946, 4142492826, 1728879713, 2882767088, 1783734482, 3629395816, 2517608232, 2874225571, 1861159788, 326777828, 3124490320, 2130389656, 2716951837, 967770486, 1724537150, 2185432712, 2364442137, 1164943284, 2105845187, 998989502, 3765401048, 2244026483, 1075463327, 1455516326, 1322494562, 910128902, 469688178, 1117454909, 936433444, 3490320968, 3675253459, 1240580251, 122909385, 2157517691, 634681816, 4142456567, 3825094682, 3061402683, 2540495037, 79693498, 3249098678, 1084186820, 1583128258, 426386531, 1761308591, 1047286709, 322548459, 995290223, 1845252383, 2603652396, 3431023940, 2942221577, 3202600964, 3727903485, 1712269319, 422464435, 3234572375, 1170764815, 3523960633, 3117677531, 1434042557, 442511882, 3600875718, 1076654713, 1738483198, 4213154764, 2393238008, 3677496056, 1014306527, 4251020053, 793779912, 2902807211, 842905082, 4246964064, 1395751752, 1040244610, 2656851899, 3396308128, 445077038, 3742853595, 3577915638, 679411651, 2892444358, 2354009459, 1767581616, 3150600392, 3791627101, 3102740896, 284835224, 4246832056, 1258075500, 768725851, 2589189241, 3069724005, 3532540348, 1274779536, 3789419226, 2764799539, 1660621633, 3471099624, 4011903706, 913787905, 3497959166, 737222580, 2514213453, 2928710040, 3937242737, 1804850592, 3499020752, 2949064160, 2386320175, 2390070455, 2415321851, 4061277028, 2290661394, 2416832540, 1336762016, 1754252060, 3520065937, 3014181293, 791618072, 3188594551, 3933548030, 2332172193, 3852520463, 3043980520, 413987798, 3465142937, 3030929376, 4245938359, 2093235073, 3534596313, 375366246, 2157278981, 2479649556, 555357303, 3870105701, 2008414854, 3344188149, 4221384143, 3956125452, 2067696032, 3594591187, 2921233993, 2428461, 544322398, 577241275, 1471733935, 610547355, 4027169054, 1432588573, 1507829418, 2025931657, 3646575487, 545086370, 48609733, 2200306550, 1653985193, 298326376, 1316178497, 3007786442, 2064951626, 458293330, 2589141269, 3591329599, 3164325604, 727753846, 2179363840, 146436021, 1461446943, 4069977195, 705550613, 3059967265, 3887724982, 4281599278, 3313849956, 1404054877, 2845806497, 146425753, 1854211946),
731 array(1266315497, 3048417604, 3681880366, 3289982499, 2909710000, 1235738493, 2632868024, 2414719590, 3970600049, 1771706367, 1449415276, 3266420449, 422970021, 1963543593, 2690192192, 3826793022, 1062508698, 1531092325, 1804592342, 2583117782, 2714934279, 4024971509, 1294809318, 4028980673, 1289560198, 2221992742, 1669523910, 35572830, 157838143, 1052438473, 1016535060, 1802137761, 1753167236, 1386275462, 3080475397, 2857371447, 1040679964, 2145300060, 2390574316, 1461121720, 2956646967, 4031777805, 4028374788, 33600511, 2920084762, 1018524850, 629373528, 3691585981, 3515945977, 2091462646, 2486323059, 586499841, 988145025, 935516892, 3367335476, 2599673255, 2839830854, 265290510, 3972581182, 2759138881, 3795373465, 1005194799, 847297441, 406762289, 1314163512, 1332590856, 1866599683, 4127851711, 750260880, 613907577, 1450815602, 3165620655, 3734664991, 3650291728, 3012275730, 3704569646, 1427272223, 778793252, 1343938022, 2676280711, 2052605720, 1946737175, 3164576444, 3914038668, 3967478842, 3682934266, 1661551462, 3294938066, 4011595847, 840292616, 3712170807, 616741398, 312560963, 711312465, 1351876610, 322626781, 1910503582, 271666773, 2175563734, 1594956187, 70604529, 3617834859, 1007753275, 1495573769, 4069517037, 2549218298, 2663038764, 504708206, 2263041392, 3941167025, 2249088522, 1514023603, 1998579484, 1312622330, 694541497, 2582060303, 2151582166, 1382467621, 776784248, 2618340202, 3323268794, 2497899128, 2784771155, 503983604, 4076293799, 907881277, 423175695, 432175456, 1378068232, 4145222326, 3954048622, 3938656102, 3820766613, 2793130115, 2977904593, 26017576, 3274890735, 3194772133, 1700274565, 1756076034, 4006520079, 3677328699, 720338349, 1533947780, 354530856, 688349552, 3973924725, 1637815568, 332179504, 3949051286, 53804574, 2852348879, 3044236432, 1282449977, 3583942155, 3416972820, 4006381244, 1617046695, 2628476075, 3002303598, 1686838959, 431878346, 2686675385, 1700445008, 1080580658, 1009431731, 832498133, 3223435511, 2605976345, 2271191193, 2516031870, 1648197032, 4164389018, 2548247927, 300782431, 375919233, 238389289, 3353747414, 2531188641, 2019080857, 1475708069, 455242339, 2609103871, 448939670, 3451063019, 1395535956, 2413381860, 1841049896, 1491858159, 885456874, 4264095073, 4001119347, 1565136089, 3898914787, 1108368660, 540939232, 1173283510, 2745871338, 3681308437, 4207628240, 3343053890, 4016749493, 1699691293, 1103962373, 3625875870, 2256883143, 3830138730, 1031889488, 3479347698, 1535977030, 4236805024, 3251091107, 2132092099, 1774941330, 1199868427, 1452454533, 157007616, 2904115357, 342012276, 595725824, 1480756522, 206960106, 497939518, 591360097, 863170706, 2375253569, 3596610801, 1814182875, 2094937945, 3421402208, 1082520231, 3463918190, 2785509508, 435703966, 3908032597, 1641649973, 2842273706, 3305899714, 1510255612, 2148256476, 2655287854, 3276092548, 4258621189, 236887753, 3681803219, 274041037, 1734335097, 3815195456, 3317970021, 1899903192, 1026095262, 4050517792, 356393447, 2410691914, 3873677099, 3682840055),
732 array(3913112168, 2491498743, 4132185628, 2489919796, 1091903735, 1979897079, 3170134830, 3567386728, 3557303409, 857797738, 1136121015, 1342202287, 507115054, 2535736646, 337727348, 3213592640, 1301675037, 2528481711, 1895095763, 1721773893, 3216771564, 62756741, 2142006736, 835421444, 2531993523, 1442658625, 3659876326, 2882144922, 676362277, 1392781812, 170690266, 3921047035, 1759253602, 3611846912, 1745797284, 664899054, 1329594018, 3901205900, 3045908486, 2062866102, 2865634940, 3543621612, 3464012697, 1080764994, 553557557, 3656615353, 3996768171, 991055499, 499776247, 1265440854, 648242737, 3940784050, 980351604, 3713745714, 1749149687, 3396870395, 4211799374, 3640570775, 1161844396, 3125318951, 1431517754, 545492359, 4268468663, 3499529547, 1437099964, 2702547544, 3433638243, 2581715763, 2787789398, 1060185593, 1593081372, 2418618748, 4260947970, 69676912, 2159744348, 86519011, 2512459080, 3838209314, 1220612927, 3339683548, 133810670, 1090789135, 1078426020, 1569222167, 845107691, 3583754449, 4072456591, 1091646820, 628848692, 1613405280, 3757631651, 526609435, 236106946, 48312990, 2942717905, 3402727701, 1797494240, 859738849, 992217954, 4005476642, 2243076622, 3870952857, 3732016268, 765654824, 3490871365, 2511836413, 1685915746, 3888969200, 1414112111, 2273134842, 3281911079, 4080962846, 172450625, 2569994100, 980381355, 4109958455, 2819808352, 2716589560, 2568741196, 3681446669, 3329971472, 1835478071, 660984891, 3704678404, 4045999559, 3422617507, 3040415634, 1762651403, 1719377915, 3470491036, 2693910283, 3642056355, 3138596744, 1364962596, 2073328063, 1983633131, 926494387, 3423689081, 2150032023, 4096667949, 1749200295, 3328846651, 309677260, 2016342300, 1779581495, 3079819751, 111262694, 1274766160, 443224088, 298511866, 1025883608, 3806446537, 1145181785, 168956806, 3641502830, 3584813610, 1689216846, 3666258015, 3200248200, 1692713982, 2646376535, 4042768518, 1618508792, 1610833997, 3523052358, 4130873264, 2001055236, 3610705100, 2202168115, 4028541809, 2961195399, 1006657119, 2006996926, 3186142756, 1430667929, 3210227297, 1314452623, 4074634658, 4101304120, 2273951170, 1399257539, 3367210612, 3027628629, 1190975929, 2062231137, 2333990788, 2221543033, 2438960610, 1181637006, 548689776, 2362791313, 3372408396, 3104550113, 3145860560, 296247880, 1970579870, 3078560182, 3769228297, 1714227617, 3291629107, 3898220290, 166772364, 1251581989, 493813264, 448347421, 195405023, 2709975567, 677966185, 3703036547, 1463355134, 2715995803, 1338867538, 1343315457, 2802222074, 2684532164, 233230375, 2599980071, 2000651841, 3277868038, 1638401717, 4028070440, 3237316320, 6314154, 819756386, 300326615, 590932579, 1405279636, 3267499572, 3150704214, 2428286686, 3959192993, 3461946742, 1862657033, 1266418056, 963775037, 2089974820, 2263052895, 1917689273, 448879540, 3550394620, 3981727096, 150775221, 3627908307, 1303187396, 508620638, 2975983352, 2726630617, 1817252668, 1876281319, 1457606340, 908771278, 3720792119, 3617206836, 2455994898, 1729034894, 1080033504),
733 array(976866871, 3556439503, 2881648439, 1522871579, 1555064734, 1336096578, 3548522304, 2579274686, 3574697629, 3205460757, 3593280638, 3338716283, 3079412587, 564236357, 2993598910, 1781952180, 1464380207, 3163844217, 3332601554, 1699332808, 1393555694, 1183702653, 3581086237, 1288719814, 691649499, 2847557200, 2895455976, 3193889540, 2717570544, 1781354906, 1676643554, 2592534050, 3230253752, 1126444790, 2770207658, 2633158820, 2210423226, 2615765581, 2414155088, 3127139286, 673620729, 2805611233, 1269405062, 4015350505, 3341807571, 4149409754, 1057255273, 2012875353, 2162469141, 2276492801, 2601117357, 993977747, 3918593370, 2654263191, 753973209, 36408145, 2530585658, 25011837, 3520020182, 2088578344, 530523599, 2918365339, 1524020338, 1518925132, 3760827505, 3759777254, 1202760957, 3985898139, 3906192525, 674977740, 4174734889, 2031300136, 2019492241, 3983892565, 4153806404, 3822280332, 352677332, 2297720250, 60907813, 90501309, 3286998549, 1016092578, 2535922412, 2839152426, 457141659, 509813237, 4120667899, 652014361, 1966332200, 2975202805, 55981186, 2327461051, 676427537, 3255491064, 2882294119, 3433927263, 1307055953, 942726286, 933058658, 2468411793, 3933900994, 4215176142, 1361170020, 2001714738, 2830558078, 3274259782, 1222529897, 1679025792, 2729314320, 3714953764, 1770335741, 151462246, 3013232138, 1682292957, 1483529935, 471910574, 1539241949, 458788160, 3436315007, 1807016891, 3718408830, 978976581, 1043663428, 3165965781, 1927990952, 4200891579, 2372276910, 3208408903, 3533431907, 1412390302, 2931980059, 4132332400, 1947078029, 3881505623, 4168226417, 2941484381, 1077988104, 1320477388, 886195818, 18198404, 3786409000, 2509781533, 112762804, 3463356488, 1866414978, 891333506, 18488651, 661792760, 1628790961, 3885187036, 3141171499, 876946877, 2693282273, 1372485963, 791857591, 2686433993, 3759982718, 3167212022, 3472953795, 2716379847, 445679433, 3561995674, 3504004811, 3574258232, 54117162, 3331405415, 2381918588, 3769707343, 4154350007, 1140177722, 4074052095, 668550556, 3214352940, 367459370, 261225585, 2610173221, 4209349473, 3468074219, 3265815641, 314222801, 3066103646, 3808782860, 282218597, 3406013506, 3773591054, 379116347, 1285071038, 846784868, 2669647154, 3771962079, 3550491691, 2305946142, 453669953, 1268987020, 3317592352, 3279303384, 3744833421, 2610507566, 3859509063, 266596637, 3847019092, 517658769, 3462560207, 3443424879, 370717030, 4247526661, 2224018117, 4143653529, 4112773975, 2788324899, 2477274417, 1456262402, 2901442914, 1517677493, 1846949527, 2295493580, 3734397586, 2176403920, 1280348187, 1908823572, 3871786941, 846861322, 1172426758, 3287448474, 3383383037, 1655181056, 3139813346, 901632758, 1897031941, 2986607138, 3066810236, 3447102507, 1393639104, 373351379, 950779232, 625454576, 3124240540, 4148612726, 2007998917, 544563296, 2244738638, 2330496472, 2058025392, 1291430526, 424198748, 50039436, 29584100, 3605783033, 2429876329, 2791104160, 1057563949, 3255363231, 3075367218, 3463963227, 1469046755, 985887462)
734 );
735 }
736}
737
738class Rational_Meta_Box
739{
740 private $screens = array('ads');
741 private $fields = array(
742 array('id' => 'sora_textarea', 'label' => 'Ad Code', 'type' => 'textarea')
743 );
744
745 /**
746 * Class construct method. Adds actions to their respective WordPress hooks.
747 */
748 public function __construct()
749 {
750 add_action('add_meta_boxes', array($this, 'add_meta_boxes'));
751 add_action('save_post', array($this, 'save_post'));
752 }
753
754 /**
755 * Hooks into WordPress' add_meta_boxes function.
756 * Goes through screens (post types) and adds the meta box.
757 */
758 public function add_meta_boxes()
759 {
760 foreach ($this->screens as $screen) {
761 add_meta_box('insert-ad-code', __('Insert Ad Code', 'rational-metabox'), array($this, 'add_meta_box_callback'), $screen, 'advanced', 'default');
762 }
763 }
764
765 /**
766 * Generates the HTML for the meta box
767 *
768 * @param object $post WordPress post object
769 */
770 public function add_meta_box_callback($post)
771 {
772 wp_nonce_field('insert_ad_code_data', 'insert_ad_code_nonce');
773 $this->generate_fields($post);
774 }
775
776 /**
777 * Generates the field's HTML for the meta box.
778 */
779 public function generate_fields($post)
780 {
781 $output = '';
782
783 foreach ($this->fields as $field) {
784 $label = '<label for="' . $field['id'] . '">' . $field['label'] . '</label>';
785 $db_value = get_post_meta($post->ID, 'insert_ad_code_' . $field['id'], true);
786
787 switch ($field['type']) {
788 case 'textarea':
789 $input = sprintf('<textarea class="large-text" id="%s" name="%s" rows="5">%s</textarea>', $field['id'], $field['id'], $db_value);
790 break;
791 }
792
793 $input = (, $field['type'] !== 'color' ? 'class="regular-text"' : '', $field['id'], $field['id'], $field['type'], $db_value);
794 $output .= $this->row_format($label, $input);
795 }
796
797 echo '<table class="form-table"><tbody>' . $output . '</tbody></table>';
798 }
799
800 /**
801 * Generates the HTML for table rows.
802 */
803 public function row_format($label, $input)
804 {
805 return sprintf('<tr><th scope="row">%s</th><td>%s</td></tr>', $label, $input);
806 }
807
808 /**
809 * Hooks into WordPress' save_post function
810 */
811 public function save_post($post_id)
812 {
813 if (!isset($_POST['insert_ad_code_nonce'])) {
814 return $post_id;
815 }
816
817 $nonce = $_POST['insert_ad_code_nonce'];
818
819 if (!wp_verify_nonce($nonce, 'insert_ad_code_data')) {
820 return $post_id;
821 }
822
823 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
824 return $post_id;
825 }
826
827 foreach ($this->fields as $field) {
828 if (isset($_POST[$field['id']])) {
829 switch ($field['type']) {
830 case 'email':
831 $_POST[$field['id']] = sanitize_email($_POST[$field['id']]);
832 break;
833
834 case 'text':
835 $_POST[$field['id']] = sanitize_text_field($_POST[$field['id']]);
836 break;
837 }
838
839 update_post_meta($post_id, 'insert_ad_code_' . $field['id'], $_POST[$field['id']]);
840 }
841 else if ($field['type'] === 'checkbox') {
842 update_post_meta($post_id, 'insert_ad_code_' . $field['id'], '0');
843 }
844 }
845 }
846}
847
848function sora_ads()
849{
850 $labels = array('name' => _x('Ads', 'Post Type General Name', 'text_domain'), 'singular_name' => _x('Ads', 'Post Type Singular Name', 'text_domain'), 'menu_name' => __('Ads', 'text_domain'), 'name_admin_bar' => __('Ads', 'text_domain'), 'archives' => __('Ads Archives', 'text_domain'), 'parent_item_colon' => __('Parent Ads:', 'text_domain'), 'all_items' => __('All Ads', 'text_domain'), 'add_new_item' => __('Add New Ads', 'text_domain'), 'add_new' => __('Add New', 'text_domain'), 'new_item' => __('New Ads', 'text_domain'), 'edit_item' => __('Edit Ads', 'text_domain'), 'update_item' => __('Update Ads', 'text_domain'), 'view_item' => __('View Ads', 'text_domain'), 'search_items' => __('Search Ads', 'text_domain'), 'not_found' => __('Not found', 'text_domain'), 'not_found_in_trash' => __('Not found in Trash', 'text_domain'), 'featured_image' => __('Featured Image', 'text_domain'), 'set_featured_image' => __('Set featured image', 'text_domain'), 'remove_featured_image' => __('Remove featured image', 'text_domain'), 'use_featured_image' => __('Use as featured image', 'text_domain'), 'insert_into_item' => __('Insert into ads', 'text_domain'), 'uploaded_to_this_item' => __('Uploaded to this ads', 'text_domain'), 'items_list' => __('Adss list', 'text_domain'), 'items_list_navigation' => __('Adss list navigation', 'text_domain'), 'filter_items_list' => __('Filter ads list', 'text_domain'));
851 $args = array(
852 'label' => __('Ads', 'text_domain'),
853 'description' => __('Ads Management', 'text_domain'),
854 'labels' => $labels,
855 'supports' => array('title'),
856 'hierarchical' => false,
857 'public' => true,
858 'show_ui' => true,
859 'show_in_menu' => false,
860 'menu_position' => 5,
861 'show_in_admin_bar' => true,
862 'show_in_nav_menus' => true,
863 'can_export' => true,
864 'has_archive' => true,
865 'exclude_from_search' => false,
866 'publicly_queryable' => true,
867 'rewrite' => false,
868 'capability_type' => 'post'
869 );
870 register_post_type('Ads', $args);
871}
872
873function soralink_settings_link($actions, $file)
874{
875 if (false !== strpos($file, 'soralink')) {
876 $actions['settings'] = '<a href="admin.php?page=soralink_configuration">Configuration</a>';
877 }
878
879 return $actions;
880}
881
882function soralink_menu()
883{
884 add_menu_page('SoraLink Plugin Settings', 'SoraLink', 'administrator', 'soralink_configuration', 'soralink_configuration', 'dashicons-editor-code', 81);
885 add_submenu_page('soralink_configuration', 'SoraLink Configuration', 'Configuration', 'administrator', 'soralink_configuration', 'soralink_configuration');
886 add_submenu_page('soralink_configuration', 'Generate Link', 'Generate Link', 'administrator', 'soralink_generate', 'soralink_generate');
887 add_submenu_page('soralink_configuration', __('Bottom Ads', 'bottom-ads'), __('Bottom Ads', 'bottom-ads'), 'manage_options', 'edit.php?post_type=ads');
888 add_submenu_page('soralink_configuration', 'SoraLink Setup', 'Setup', 'administrator', 'soralink_setup', 'soralink_setup');
889 $submenu['soralink_configuration'][0][0] = 'Dashboard';
890 add_action('admin_init', 'register_soralink_settings');
891}
892
893function register_soralink_settings()
894{
895 register_setting('soralink-settings', 'soralinkkey');
896 register_setting('soralink-settings', 'soralinkkeycache');
897 register_setting('soralink-settings', 'secretkeyserver');
898 register_setting('soralink-settings', 'ads_top');
899 register_setting('soralink-settings', 'ads_content');
900 register_setting('soralink-settings', 'start_date');
901 register_setting('soralink-settings', 'end_date');
902 register_setting('soralink-settings', 'countdown');
903 register_setting('soralink-settings', 'countdowntop');
904 register_setting('soralink-settings', 'singlecountdown');
905}
906
907function soralink_configuration()
908{
909 function askVerifyAndSaveLicenseKey()
910 {
911 if (empty($_POST['soralinkkey'])) {
912 renderLicenseForm('Please enter a license key');
913 exit();
914 }
915 else {
916 $license_key = preg_replace('/[^A-Za-z0-9-_]/', '', trim($_POST['soralinkkey']));
917 }
918
919 $checker = new Am_LicenseChecker($license_key, API_URL);
920
921 if (!$checker->checkLicenseKey()) {
922 renderLicenseForm($checker->getMessage());
923 exit();
924 }
925 else {
926 update_option('soralinkkey', $license_key, '', 'yes');
927 return $license_key;
928 }
929 }
930 function renderLicenseForm($errorMsg = NULL)
931 {
932 echo ' <div class="update-nag notice" style="display: block;">';
933 echo $errorMsg;
934 echo '</div>' . "\n" . ' <form class="form" method="post" action="options.php">' . "\n" . ' ';
935 settings_fields('soralink-settings');
936 echo ' ';
937 do_settings_sections('soralink-settings');
938 echo ' <input type="text" name="soralinkkey" class="regular-text" value="';
939 echo esc_attr(get_option('soralinkkey'));
940 echo '" placeholder="Insert valid license..." />' . "\n" . ' ';
941 submit_button();
942 echo ' </form>' . "\n";
943 }
944 echo '<style>' . "\n" . '.wrap {' . "\n" . ' padding: 10px 20px;' . "\n" . ' order: 1px solid #e5e5e5;' . "\n" . ' -webkit-box-shadow: 0 1px 1px rgba(0,0,0,.04);' . "\n" . ' box-shadow: 0 1px 1px rgba(0,0,0,.04);' . "\n" . ' background: #fff;' . "\n" . '}' . "\n" . '.wrap h1 {' . "\n" . ' margin: -10px -20px;' . "\n" . ' margin-bottom: 10px;' . "\n" . ' padding: 10px 20px;' . "\n" . ' font-size: 17px;' . "\n" . ' font-weight: bold;' . "\n" . ' background: #F7F7F7;' . "\n" . ' border-bottom: 1px solid #EFEFEF;' . "\n" . '}' . "\n" . '</style>' . "\n" . '<div class="wrap">' . "\n" . '<h1>SoraLink Configuration</h1>' . "\n";
945 $license_key = get_option('soralinkkey');
946
947 if (!strlen($license_key)) {
948 $license_key = askVerifyAndSaveLicenseKey();
949 }
950
951 echo "\n" . '<form method="post" action="options.php">' . "\n" . ' ';
952 settings_fields('soralink-settings');
953 echo ' ';
954 do_settings_sections('soralink-settings');
955 echo ' <table class="form-table">' . "\n" . ' <tr valign="top">' . "\n" . ' <th scope="row">License</th>' . "\n" . ' <td><input type="text" name="soralinkkey" class="regular-text" value="';
956 echo esc_attr(get_option('soralinkkey'));
957 echo '" placeholder="Insert valid license..." /></td>' . "\n" . ' </tr>' . "\n" . ' <tr valign="top">' . "\n" . ' <th scope="row">Secret Key</th>' . "\n" . ' <td><input type="text" name="secretkeyserver" class="regular-text" value="';
958 echo esc_attr(get_option('secretkeyserver'));
959 echo '" placeholder="Insert your secret key..." /></td>' . "\n" . ' </tr>' . "\n" . ' <tr valign="top">' . "\n" . ' <th scope="row">Ads Top</th>' . "\n" . ' <td><textarea type="text/javascript" name="ads_top" rows="10" cols="50" value="';
960 echo esc_attr(get_option('ads_top'));
961 echo '" class="large-text code" placeholder="Place your ads code here. Recommended size 728x90">';
962 echo esc_attr(get_option('ads_top'));
963 echo '</textarea></td>' . "\n" . ' </tr>' . "\n" . ' <tr valign="top">' . "\n" . ' <th scope="row">Ads Content</th>' . "\n" . ' <td><textarea type="text/javascript" name="ads_content" rows="10" cols="50" value="';
964 echo esc_attr(get_option('ads_content'));
965 echo '" class="large-text code" placeholder="Place your ads code here. Recommended responsive size or 300x250">';
966 echo esc_attr(get_option('ads_content'));
967 echo '</textarea></td>' . "\n" . ' </tr>' . "\n" . ' <tr valign="top">' . "\n" . ' <th scope="row">Hide Ads by Range Date</th>' . "\n" . ' <td><input type="number" name="start_date" min="0" class="small-text" value="';
968 echo esc_attr(get_option('start_date'));
969 echo '" placeholder="start" />' . "\n\t" . '<label for="range">until</label>' . "\n\t" . '<input type="number" name="end_date" min="0" class="small-text" value="';
970 echo esc_attr(get_option('end_date'));
971 echo '" placeholder="end" />' . "\n\t" . '</td>' . "\n" . ' </tr>' . "\n" . ' <tr valign="top">' . "\n" . ' <th scope="row">Countdown Top</th>' . "\n" . ' <td><input type="number" name="countdowntop" min="1" class="small-text" value="';
972 echo esc_attr(get_option('countdowntop'));
973 echo '" /></td>' . "\n" . ' </tr>' . "\n" . ' <tr valign="top">' . "\n" . ' <th scope="row">Countdown Bottom</th>' . "\n" . ' <td><input type="number" name="countdown" class="small-text" value="';
974 echo esc_attr(get_option('countdown'));
975 echo '" /></td>' . "\n" . ' </tr>' . "\n" . ' <tr valign="top">' . "\n" . ' <th scope="row">Countdown Single</th>' . "\n" . ' <td><input type="number" name="singlecountdown" min="0" class="small-text" value="';
976 echo esc_attr(get_option('singlecountdown'));
977 echo '" /></td>' . "\n" . ' </tr>' . "\n" . ' </table> ' . "\n" . ' ';
978 submit_button();
979 echo "\n" . '</form>' . "\n" . '</div>' . "\n";
980}
981
982function soralink_generate()
983{
984 echo '<script language="javascript">' . "\n" . 'function select_all(obj) {' . "\n" . ' var text_val=eval(obj);' . "\n" . ' text_val.focus();' . "\n" . ' text_val.select();' . "\n" . ' if (!document.all) return; // IE only' . "\n" . ' r = text_val.createTextRange();' . "\n" . ' r.execCommand(\'copy\');' . "\n" . '}' . "\n" . 'function generatelink()' . "\n" . '{' . "\n" . 'var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\\+\\/\\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\\r\\n/g,"\\n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}}' . "\n" . 'generate=document.glink.generate.value;' . "\n" . 'encodedString = Base64.encode(generate);' . "\n" . 'document.glink.result.value=\'';
985 echo get_site_url();
986 echo '/?r=\'+encodedString+\'#landing\';' . "\n" . '}' . "\n" . '</script>' . "\n" . '<div class="wrap">' . "\n" . '<h1>Generate Link</h1>' . "\n" . '<form name="glink">' . "\n" . ' <table class="form-table">' . "\n" . ' <tr valign="top">' . "\n" . ' <th scope="row">Generate</th>' . "\n" . ' <td>' . "\n" . ' ' . "\t" . '<input type="url" name="generate" class="regular-text" size="60" placeholder="Insert url here..." />' . "\n" . ' ' . "\t" . '<input type="button" name="go" id="submit" class="button button-primary" value="Go" onclick="generatelink()">' . "\n" . ' </td>' . "\n" . ' </tr>' . "\n" . ' <tr valign="top">' . "\n" . ' <th scope="row">Result</th>' . "\n" . ' <td>' . "\n" . ' ' . "\t" . '<input type="text" name="result" class="large-text" placeholder="result generate link" onclick="select_all(this)" readonly/>' . "\n" . ' </td>' . "\n" . ' </tr>' . "\n" . ' </table>' . "\n" . ' </form>' . "\n" . '</div>' . "\n";
987}
988
989function soralink_setup()
990{
991 echo '<div class="wrap">' . "\n" . '<script type="text/javascript">' . "\n" . ' function select_all(obj) {' . "\n" . ' var text_val=eval(obj);' . "\n" . ' text_val.focus();' . "\n" . ' text_val.select();' . "\n" . ' if (!document.all) return; // IE only' . "\n" . ' r = text_val.createTextRange();' . "\n" . ' r.execCommand(\'copy\');' . "\n" . ' }' . "\n" . '</script>' . "\n" . '<h1>SoraLink Setup</h1>' . "\n" . '<h2>Installation</h2>' . "\n" . 'Place this code <b>after</b> <?php get_header(); ?> in index.php theme.<br>' . "\n" . '<input type="text" class="large-text code" value="<?php if(function_exists(\'humancheck_sora\')){humancheck_sora(\'Human Verification\',1);} ?>" onclick="select_all(this)" readonly /><br><br>' . "\n" . 'Place this code <b>after</b> <?php get_header(); ?> in single.php theme.<br>' . "\n" . '<input type="text" class="large-text code" value="<?php if(function_exists(\'start_sora\')){start_sora();} ?>" onclick="select_all(this)" readonly /><br><br>' . "\n" . 'Place this code <b>before</b> <?php get_footer(); ?> in single.php theme.<br>' . "\n" . '<input type="text" class="large-text code" value="<?php if(function_exists(\'end_sora\')){end_sora();} ?>" onclick="select_all(this)" readonly /><br><br>' . "\n" . 'Place this code <b>after</b> <?php get_header(); ?> in single.php theme <b>(if using single button)</b>.<br>' . "\n" . '<input type="text" class="large-text code" value="<?php if(function_exists(\'single_sora\')){single_sora();} ?>" onclick="select_all(this)" readonly /><br><br>' . "\n" . '<h2>Autolink Script</h2>' . "\n" . 'use this script if <b>SoraLink Client</b> not working<br><br>' . "\n" . '<textarea type="text/javascript" class="large-text code" rows="7" cols="50" onclick="select_all(this)" readonly>' . "\n" . '<script type="text/javascript" src="';
992 echo get_site_url();
993 echo '/wp-content/plugins/soralink/assets/js/sora.php"></script>' . "\n" . '<script type="text/javascript">' . "\n" . 'protected_links = "";' . "\n" . 'auto_safelink();' . "\n" . '</script></textarea><br/>' . "\n" . '<br/>' . "\n" . '</div>' . "\n";
994}
995
996ini_set('display_errors', false);
997error_reporting(32767);
998define('API_URL', 'http://enduser.id/member/softsale/api');
999new Rational_Meta_Box();
1000add_action('init', 'sora_ads', 0);
1001add_filter('plugin_action_links', 'soralink_settings_link', 2, 2);
1002add_action('admin_menu', 'soralink_menu');
1003$soralinkkey = get_option('soralinkkey');
1004$license_key = get_option('soralinkkey');
1005$activation_cache = get_option('soralinkkeycache');
1006$prev_activation_cache = $activation_cache;
1007$checker = new Am_LicenseChecker($license_key, API_URL);
1008$ret = (empty($activation_cache) ? $checker->activate($activation_cache) : $checker->checkActivation($activation_cache));
1009
1010if ($prev_activation_cache != $activation_cache) {
1011 update_option('soralinkkeycache', $activation_cache, '', 'yes');
1012}
1013
1014if (!$ret) {
1015 function soralinkinvalid()
1016 {
1017 echo ' <div class="error notice">' . "\n" . ' <p>SoraLink Invalid Key</p>' . "\n" . ' </div>' . "\n" . ' ';
1018 }
1019 add_action('admin_notices', 'soralinkinvalid');
1020}
1021else {
1022 function sora_client_encrypt_decrypt_xxxxxxxxx($action, $string)
1023 {
1024 $output = false;
1025 $encrypt_method = 'AES-256-CBC';
1026 $secret_key = md5(get_option('secretkeyserver'));
1027 $secret_iv = get_option('secretkeyserver');
1028 $key = hash('sha256', $secret_key);
1029 $iv = substr(hash('sha256', $secret_iv), 0, 16);
1030
1031 if ($action == 'encrypt') {
1032 $output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
1033 $output = base64_encode($output);
1034 }
1035 else if ($action == 'decrypt') {
1036 $output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
1037 }
1038
1039 return $output;
1040 }
1041 function delayjs()
1042 {
1043 $cd = get_option('countdown');
1044 if (($cd == '0') || ($cd == '')) {
1045 $cd = 5;
1046 }
1047 else {
1048 $cd = get_option('countdown');
1049 }
1050
1051 if (isset($_POST['d'])) {
1052 echo '<script type=\'text/javascript\'>' . "\n" . 'function generate(){$("#showlink").delay(';
1053 echo $cd;
1054 echo '000).fadeIn("fast");$("#pleasewaits").fadeIn("fast");var timer=setInterval(function(){$("#pleasewaits").fadeOut("fast")},';
1055 echo $cd;
1056 echo '000);}function base64_decode(w){var m,b,z,k,x,q,A,y,v="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",s=0,j=0,u="",p=[];if(!w){return w}w+="";do{k=v.indexOf(w.charAt(s++)),x=v.indexOf(w.charAt(s++)),q=v.indexOf(w.charAt(s++)),A=v.indexOf(w.charAt(s++)),y=k<<18|x<<12|q<<6|A,m=y>>16&255,b=y>>8&255,z=255&y,64==q?p[j++]=String.fromCharCode(m):64==A?p[j++]=String.fromCharCode(m,b):p[j++]=String.fromCharCode(m,b,z)}while(s<w.length);return u=p.join(""),decodeURIComponent(escape(u.replace(/\\0+$/,"")))}function changeLink(){var a=base64_decode("';
1057 echo $_POST['d'];
1058 echo '");window.open(a,"_blank")};' . "\n" . '</script>' . "\n";
1059 }
1060 else if (isset($_POST['get'])) {
1061 echo '<script type=\'text/javascript\'>' . "\n" . 'function generate(){$("#showlink").delay(';
1062 echo $cd;
1063 echo '000).fadeIn("fast");$("#pleasewaits").fadeIn("fast");var timer=setInterval(function(){$("#pleasewaits").fadeOut("fast")},';
1064 echo $cd;
1065 echo '000);}function changeLink(){var a=\'';
1066 echo sora_client_encrypt_decrypt_xxxxxxxxx('decrypt', $_POST['get']);
1067 echo '\';window.open(a,"_blank")};' . "\n" . '</script>' . "\n";
1068 }
1069 }
1070 function humancheck_sora($halo, $status)
1071 {
1072 if (isset($_GET['r']) || isset($_GET['id'])) {
1073 $args = array('post_type' => 'post', 'orderby' => 'rand', 'posts_per_page' => 1, 'no_found_rows' => true, 'update_post_term_cache' => false, 'update_post_meta_cache' => false, 'cache_results' => false);
1074 $the_query = new WP_Query($args);
1075
1076 if ($the_query->have_posts()) {
1077 while ($the_query->have_posts()) {
1078 $the_query->the_post();
1079 echo '<div class="humancheck" id="srl">' . "\n\t" . '<div class="helloworld">';
1080 echo $halo;
1081 echo '</div>' . "\n\t" . '<form action="';
1082 the_permalink();
1083 echo '" method="post">' . "\n\t\t";
1084
1085 if (isset($_GET['r'])) {
1086 echo "\t\t\t" . '<input type="hidden" name="d" value="';
1087 echo $_GET['r'];
1088 echo '">' . "\n\t\t";
1089 }
1090 else if (isset($_GET['id'])) {
1091 echo "\t\t\t" . '<input type="hidden" name="get" value="';
1092 echo $_GET['id'];
1093 echo '">' . "\n\t\t";
1094 }
1095
1096 echo "\t" . ' <input class="sorasubmit" type="submit" value="Submit">' . "\n\t" . '</form>' . "\n" . '</div>' . "\n";
1097 }
1098 }
1099
1100 if ($status == 1) {
1101 exit();
1102 }
1103 }
1104 }
1105 function start_sora()
1106 {
1107 if (isset($_POST['d']) || isset($_POST['get'])) {
1108 echo "\t\t" . '<div id="landing" class="soractrl">' . "\n";
1109 $now = date('d');
1110 $start = get_option('start_date');
1111 $end = get_option('end_date');
1112
1113 if (true === in_array($now, range($start, $end))) {
1114 }
1115 else {
1116 echo "\t\t\t" . '<div class="adsora">';
1117 $top = get_option('ads_top');
1118
1119 if ($top) {
1120 echo $top;
1121 }
1122
1123 echo '</div>' . "\n";
1124 }
1125
1126 $cdx = get_option('countdowntop');
1127 echo '<script>' . "\n" . ' var timeout,interval' . "\n" . ' var threshold = ';
1128 echo $cdx;
1129 echo '000;' . "\n" . ' var secondsleft=threshold;' . "\n\n" . ' window.onload = function()' . "\n" . ' {' . "\n" . ' startschedule();' . "\n" . ' }' . "\n\n" . ' function startChecking()' . "\n" . ' {' . "\n" . ' secondsleft-=1000;' . "\n" . ' document.querySelector(".wait"); ' . "\n" . ' if(secondsleft == 0)' . "\n" . ' {' . "\n" . ' //document.getElementById("clickme").style.display="";' . "\n" . ' clearInterval(interval);' . "\n" . ' document.querySelector(".wait").style.display="none";' . "\n" . ' document.querySelector(".to").style.display="";' . "\n" . ' }' . "\n" . ' }' . "\n" . ' function startschedule()' . "\n" . ' {' . "\n" . ' clearInterval(interval);' . "\n" . ' secondsleft=threshold;' . "\n" . ' document.querySelector(".wait"); ' . "\n" . ' interval = setInterval(function()' . "\n" . ' {' . "\n" . ' startChecking();' . "\n" . ' },1000) ' . "\n" . ' }' . "\n\n" . ' function resetTimer()' . "\n" . ' {' . "\n" . ' startschedule();' . "\n" . ' }' . "\n" . '</script>' . "\n" . ' <div class="wait">' . "\n" . ' ' . "\t" . '<center><img id="pleasewait" src="';
1130 bloginfo('url');
1131 echo '/wp-content/plugins/soralink/assets/img/wait.png" /></center>' . "\n" . ' </div>' . "\n\t\t\t" . '<div class="to" style="display: none;">' . "\n\t\t\t\t" . '<a href="#generate" onclick="generate()"><img src="';
1132 bloginfo('url');
1133 echo '/wp-content/plugins/soralink/assets/img/start.png" /></a>' . "\n\t\t\t" . '</div>' . "\n\t\t" . '</div>' . "\n\t";
1134 }
1135 }
1136 function end_sora()
1137 {
1138 if (isset($_POST['d']) || isset($_POST['get'])) {
1139 echo "\t\t" . '<div class="soractrl">' . "\n\t\t\t" . '<div id="generate"></div>' . "\n" . ' <center><img id="pleasewaits" style="display: none;" src="';
1140 bloginfo('url');
1141 echo '/wp-content/plugins/soralink/assets/img/wait.png" /></center>' . "\n\t\t\t" . '<img class="spoint" id="showlink" onclick="changeLink()" style="display: none;" src="';
1142 bloginfo('url');
1143 echo '/wp-content/plugins/soralink/assets/img/end.png" />' . "\n";
1144 $now = date('d');
1145 $start = get_option('start_date');
1146 $end = get_option('end_date');
1147
1148 if (true === in_array($now, range($start, $end))) {
1149 }
1150 else {
1151 echo "\t\t" . '<div class="adsora">' . "\n\t\t\t";
1152 $sorads = new WP_Query('post_type=ads&orderby=rand&showposts=1');
1153
1154 while ($sorads->have_posts()) {
1155 $sorads->the_post();
1156 $meta = get_post_meta(get_the_ID(), 'insert_ad_code_sora_textarea', true);
1157 echo $meta;
1158 }
1159
1160 echo "\t\t" . '</div>' . "\n";
1161 }
1162
1163 echo "\t\t" . '</div>' . "\n\t";
1164 }
1165 }
1166 function single_sora()
1167 {
1168 if (isset($_POST['d']) || isset($_POST['get'])) {
1169 $now = date('d');
1170 $start = get_option('start_date');
1171 $end = get_option('end_date');
1172
1173 if (true === in_array($now, range($start, $end))) {
1174 }
1175 else {
1176 echo ' <div class="adsora">';
1177 $top = get_option('ads_top');
1178
1179 if ($top) {
1180 echo $top;
1181 }
1182
1183 echo '</div>' . "\n";
1184 }
1185
1186 echo ' <div class="soractrl">' . "\n" . ' <div id="landing"></div>' . "\n";
1187 $cdx = get_option('singlecountdown');
1188
1189 if ($cdx == '') {
1190 $cdx = 0;
1191 }
1192
1193 if ($cdx != '0') {
1194 echo '<script>' . "\n" . ' var timeout,interval' . "\n" . ' var threshold = ';
1195 echo $cdx;
1196 echo '000;' . "\n" . ' var secondsleft=threshold;' . "\n\n" . ' window.onload = function()' . "\n" . ' {' . "\n" . ' startschedule();' . "\n" . ' }' . "\n\n" . ' function startChecking()' . "\n" . ' {' . "\n" . ' secondsleft-=1000;' . "\n" . ' document.querySelector(".wait"); ' . "\n" . ' if(secondsleft == 0)' . "\n" . ' {' . "\n" . ' //document.getElementById("clickme").style.display="";' . "\n" . ' clearInterval(interval);' . "\n" . ' document.querySelector(".wait").style.display="none";' . "\n" . ' document.querySelector(".to").style.display="";' . "\n" . ' }' . "\n" . ' }' . "\n" . ' function startschedule()' . "\n" . ' {' . "\n" . ' clearInterval(interval);' . "\n" . ' secondsleft=threshold;' . "\n" . ' document.querySelector(".wait"); ' . "\n" . ' interval = setInterval(function()' . "\n" . ' {' . "\n" . ' startChecking();' . "\n" . ' },1000) ' . "\n" . ' }' . "\n\n" . ' function resetTimer()' . "\n" . ' {' . "\n" . ' startschedule();' . "\n" . ' }' . "\n" . '</script>' . "\n";
1197 }
1198
1199 echo ' <div class="wait" ';
1200 if (($cdx == '0') || ($cdx == '')) {
1201 echo 'style="display: none;"';
1202 }
1203
1204 echo ' >' . "\n" . ' <center><img id="pleasewait" src="';
1205 bloginfo('url');
1206 echo '/wp-content/plugins/soralink/assets/img/wait.png" /></center>' . "\n" . ' </div>' . "\n" . ' <div class="to" ';
1207
1208 if ($cdx != '0') {
1209 echo 'style="display: none;"';
1210 }
1211
1212 echo ' >' . "\n" . ' <img class="spoint" id="showlink" onclick="changeLink()" src="';
1213 bloginfo('url');
1214 echo '/wp-content/plugins/soralink/assets/img/end.png" />' . "\n" . ' </div>' . "\n" . ' </div>' . "\n" . ' ';
1215 }
1216 }
1217 function prefix_insert_post_ads($content)
1218 {
1219 $now = date('d');
1220 $start = get_option('start_date');
1221 $end = get_option('end_date');
1222
1223 if (true === in_array($now, range($start, $end))) {
1224 $ad_code = '';
1225 }
1226 else {
1227 $ad_code = '<div class="soractrl">' . get_option('ads_content') . '</div>';
1228 }
1229
1230 if (is_single() && !is_admin()) {
1231 return prefix_insert_after_paragraph($ad_code, 2, $content);
1232 }
1233
1234 return $content;
1235 }
1236 function prefix_insert_after_paragraph($insertion, $paragraph_id, $content)
1237 {
1238 $closing_p = '</p>';
1239 $paragraphs = explode($closing_p, $content);
1240
1241 foreach ($paragraphs as $index => $paragraph) {
1242 if (trim($paragraph)) {
1243 $paragraphs .= $index;
1244 }
1245
1246 if ($paragraph_id == $index + 1) {
1247 $paragraphs .= $index;
1248 }
1249 }
1250
1251 return implode('', $paragraphs);
1252 }
1253 add_action('wp_head', 'delayjs');
1254 add_filter('the_content', 'prefix_insert_post_ads');
1255}
1256
1257?>