api.paysysproto.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. <?php
  2. /**
  3. * Fronted paysys class to be inherited
  4. * Encapsulates all of the commonly used methods and props
  5. */
  6. class PaySysProto {
  7. /**
  8. * Predefined stuff
  9. * Just as an example - override this in your paysys class, if needed
  10. */
  11. /**
  12. * One may use special 'NO_INI_CONFIG' keyword for 'PATH_CONFIG' constant
  13. * to avoid the demanded usage of some 'config.ini' file.
  14. * BUT KEEP IN MIND
  15. * That in that case not even one 'Contragent-related' method will work.
  16. * Because there should be at least 'ubAPI' creds to use contragent-related stuff.
  17. * But one may implement that in own way.
  18. * And of course one may just override the value of the $INIConfigIsON flag.
  19. * Anyway - this methods will not work properly without 'config.ini' file usage:
  20. * loadAgentCodesMapping()
  21. * getUBAgentData()
  22. * getUBAgentAssignedID()
  23. * checkUserAgentAssignment()
  24. * getPaySysIDToAgentAssigned()
  25. */
  26. const PATH_CONFIG = 'config/config.ini';
  27. const PATH_AGENTCODES = 'config/agentcodes_mapping.ini';
  28. const PATH_DEBUGLOG = 'processing_debug.log';
  29. const PATH_TRANSACTS = 'tmp/';
  30. const OP_TRANSACT_TABLE = 'op_transactions';
  31. /**
  32. * Paysys specific predefines.
  33. * Just as an example - OVERRIDE THIS IN YOUR PAYSYS CLASS
  34. */
  35. const HASH_PREFIX = 'PAYSYS_HASH_';
  36. const PAYSYS = 'PAYSYS_NAME';
  37. /**
  38. * Instance configuration as key => value
  39. *
  40. * @var array
  41. */
  42. protected $config = array();
  43. /**
  44. * Just a flag indicating the 'config.ini' usage
  45. *
  46. * @var bool
  47. */
  48. protected $INIConfigIsON = true;
  49. /**
  50. * Agent codes using flag
  51. *
  52. * @var bool
  53. */
  54. protected $agentcodesON = false;
  55. /**
  56. * Non strict agent codes using flag
  57. *
  58. * @var bool
  59. */
  60. protected $agentcodesNonStrict = false;
  61. /**
  62. * Contains values from agentcodes_mapping.ini
  63. *
  64. * @var array
  65. */
  66. protected $agentcodesMapping = array();
  67. /**
  68. * Placeholder for a DISABLE_AGENTCODES_MAPPING_FILE config option
  69. *
  70. * @var bool
  71. */
  72. protected $agentcodesMappingDisable = false;
  73. /**
  74. * Placeholder for a "last resort" config option DEFAULT_AGENT_CODE
  75. *
  76. * @var int
  77. */
  78. protected $agentcodeDefault = 1;
  79. /**
  80. * Contains data of UB agent the user is assigned to
  81. *
  82. * @var array
  83. */
  84. protected $agentData = array();
  85. /**
  86. * Contains ID of UB agent the user is assigned to or zero if no assignment found
  87. *
  88. * @var array
  89. */
  90. protected $agentID = 0;
  91. /**
  92. * Placeholder for UB API URL
  93. *
  94. * @var string
  95. */
  96. protected $ubapiURL = '';
  97. /**
  98. * Placeholder for UB API key
  99. *
  100. * @var string
  101. */
  102. protected $ubapiKey = '';
  103. /**
  104. * Placeholder for CITY_DISPLAY_IN_ADDRESS config option
  105. *
  106. * @var bool
  107. */
  108. protected $addressCityDisplay = false;
  109. /**
  110. * Placeholder for SUBSCRIBER_BALANCE_DECIMALS config option
  111. *
  112. * @var bool
  113. */
  114. protected $subscriberBalanceDecimals = -1;
  115. /**
  116. * Contains value of DEBUG_MODE_ON INI option
  117. *
  118. * @var bool
  119. */
  120. protected $debugModeON = false;
  121. /**
  122. * Preloads all required configurations, sets needed object properties
  123. *
  124. * @return void
  125. */
  126. public function __construct($config_path = self::PATH_CONFIG) {
  127. $this->INIConfigIsON = ($config_path !== 'NO_INI_CONFIG');
  128. $this->loadConfig($config_path);
  129. }
  130. /**
  131. * Loads frontend configuration in protected prop
  132. *
  133. * @return void
  134. */
  135. protected function loadConfig($config_path = self::PATH_CONFIG) {
  136. if ($this->INIConfigIsON) {
  137. if (file_exists($config_path)) {
  138. $this->config = parse_ini_file($config_path);
  139. }
  140. else {
  141. $this->replyError(500, 'Fatal error: config file ' . $config_path . ' not found!');
  142. }
  143. }
  144. }
  145. /**
  146. * Sets object properties based on frontend config
  147. *
  148. * @return void
  149. */
  150. protected function setOptions() {
  151. if ($this->INIConfigIsON) {
  152. if (!empty($this->config)) {
  153. $this->agentcodesON = isset($this->config['USE_AGENTCODES']) ? $this->config['USE_AGENTCODES'] : false;
  154. $this->agentcodesMappingDisable = isset($this->config['DISABLE_AGENTCODES_MAPPING_FILE']) ? $this->config['DISABLE_AGENTCODES_MAPPING_FILE'] : false;
  155. $this->agentcodesNonStrict = isset($this->config['NON_STRICT_AGENTCODES']) ? $this->config['NON_STRICT_AGENTCODES'] : false;
  156. $this->agentcodeDefault = isset($this->config['DEFAULT_AGENT_CODE']) ? $this->config['DEFAULT_AGENT_CODE'] : 1;
  157. $this->ubapiURL = isset($this->config['UBAPI_URL']) ? $this->config['UBAPI_URL'] : '';
  158. $this->ubapiKey = isset($this->config['UBAPI_KEY']) ? $this->config['UBAPI_KEY'] : '';
  159. $this->addressCityDisplay = isset($this->config['CITY_DISPLAY_IN_ADDRESS']) ? $this->config['CITY_DISPLAY_IN_ADDRESS'] : false;
  160. $this->subscriberBalanceDecimals = isset($this->config['SUBSCRIBER_BALANCE_DECIMALS']) ? $this->config['SUBSCRIBER_BALANCE_DECIMALS'] : -1;
  161. $this->debugModeON = isset($this->config['DEBUG_MODE_ON']) ? $this->config['DEBUG_MODE_ON'] : false;
  162. } else {
  163. $this->replyError(500, 'Fatal: config is empty!');
  164. }
  165. }
  166. }
  167. /**
  168. * Loads frontend agentcodes_mapping.ini in protected prop
  169. *
  170. * @return void
  171. */
  172. protected function loadAgentCodesMapping($agent_codes_path = self::PATH_AGENTCODES) {
  173. if ($this->agentcodesON and !$this->agentcodesMappingDisable) {
  174. if (file_exists($agent_codes_path)) {
  175. $this->agentcodesMapping = parse_ini_file($agent_codes_path);
  176. } else {
  177. $this->replyError(500, 'Fatal error: agentcodes_mapping.ini file ' . $agent_codes_path . ' not found!');
  178. }
  179. }
  180. }
  181. /**
  182. * Gets user associated agent data JSON
  183. *
  184. * @param string $userLogin
  185. *
  186. * @return string
  187. */
  188. protected function getUBAgentData($userLogin) {
  189. if ($this->INIConfigIsON) {
  190. $actionURL = $this->ubapiURL . '?module=remoteapi&key=' . $this->ubapiKey . '&action=getagentdata&param=' . $userLogin;
  191. @$result = file_get_contents($actionURL);
  192. }
  193. if (empty($result)) {
  194. $result = array();
  195. } else {
  196. $result = json_decode($result, true);
  197. }
  198. $this->agentData = $result;
  199. return ($result);
  200. }
  201. /**
  202. * Gets user associated agent data JSON
  203. *
  204. * @param string $userLogin
  205. *
  206. * @return string
  207. */
  208. public static function getUBAgentDataByUBAPIURL($actionURL) {
  209. if (!empty($actionURL)) {
  210. @$result = file_get_contents($actionURL);
  211. }
  212. if (empty($result)) {
  213. $result = array();
  214. } else {
  215. $result = json_decode($result, true);
  216. }
  217. return ($result);
  218. }
  219. /**
  220. * Returns user's assigned agent extended data, if available
  221. *
  222. * @param $gentID
  223. *
  224. * @return array|empty
  225. */
  226. public static function getUBAgentDataExten($agentID = '', $paysysName = '') {
  227. $result = array();
  228. $whereStr = '';
  229. if (!empty($agentID)) { $whereStr.= ' `agentid` = ' . $agentID; }
  230. if (!empty($paysysName)) {
  231. if (!empty($whereStr)) { $whereStr.= ' and '; }
  232. $whereStr.= ' `internal_paysys_name` = "' . $paysysName . '"';
  233. }
  234. $query = 'select * from `contrahens_extinfo` where ' . $whereStr;
  235. $queryResult = simple_queryall($query);
  236. $result = (empty($queryResult) ? array() : $queryResult);
  237. return ($result);
  238. }
  239. /**
  240. * Returns user's assigned agent ID, if available
  241. *
  242. * @param $userLogin
  243. *
  244. * @return int|mixed|string
  245. */
  246. protected function getUBAgentAssignedID($userLogin) {
  247. if ($this->INIConfigIsON) {
  248. if (empty($this->agentID)) {
  249. $agentData = (empty($this->agentData) ? $this->getUBAgentData($userLogin) : $this->agentData);
  250. $this->agentID = (empty($agentData['id'])
  251. ? (empty($this->agentcodeDefault)
  252. ? 0 : (empty($this->agentcodesNonStrict)
  253. ? 0 : $this->agentcodeDefault)) : $agentData['id']);
  254. }
  255. }
  256. return ($this->agentID);
  257. }
  258. /**
  259. * Validates Paysys Service/Merchant/Cashbox/etc ID and Ubilling agent ID correlation
  260. *
  261. * @param $userLogin
  262. *
  263. * @return bool
  264. */
  265. protected function checkUserAgentAssignment($userLogin, $paysysIDToCheck) {
  266. $result = false;
  267. if ($this->INIConfigIsON) {
  268. // get current subscriber agent ID
  269. $agentID = $this->getUBAgentAssignedID($userLogin);
  270. if (!empty($agentID)) {
  271. // get Service ID to Ubilling agent code mapping, if exists
  272. $mappedAgentBySrvID = (empty($this->agentcodesMapping[$paysysIDToCheck]) ? 'n0ne'
  273. : $this->agentcodesMapping[$paysysIDToCheck]);
  274. // compare the IDs
  275. $result = ($agentID == $mappedAgentBySrvID);
  276. }
  277. // if $result is false and $this->agentcodesNonStrict is ON - make $result true
  278. $result = ((!$result and $this->agentcodesNonStrict) ? true : $result);
  279. }
  280. return ($result);
  281. }
  282. /**
  283. * Tries to get Paysys Service/Merchant/Cashbox/etc ID by Ubilling agent ID from agentcodes_mapping.ini
  284. *
  285. * @param $userLogin
  286. *
  287. * @return mixed|string
  288. */
  289. protected function getPaySysIDToAgentAssigned($userLogin) {
  290. $paysysIDToGet = '';
  291. if ($this->INIConfigIsON) {
  292. $agentcodesMappingReversed = array_flip($this->agentcodesMapping);
  293. $agentID = $this->getUBAgentAssignedID($userLogin);
  294. if (!empty($agentID)) {
  295. // get Ubilling agent code to Cashbox mapping, if exists
  296. $paysysIDToGet = (empty($agentcodesMappingReversed[$agentID]) ? '' : $agentcodesMappingReversed[$agentID]);
  297. }
  298. // if no mapped Service/Merchant/Cashbox/etc ID found or user does not have UB agent assigned
  299. // and $this->agentcodesNonStrict is ON - proceed with default UB agent ID
  300. // and a Service/Merchant/Cashbox/etc ID mapped to it
  301. // if no default UB agent ID is set - user not found error should be returned.
  302. if (empty($paysysIDToGet) and $this->agentcodesNonStrict and !empty($this->agentcodeDefault)) {
  303. $paysysIDToGet = (empty($agentcodesMappingReversed[$this->agentcodeDefault])
  304. ? ''
  305. : $agentcodesMappingReversed[$this->agentcodeDefault]);
  306. }
  307. }
  308. return ($paysysIDToGet);
  309. }
  310. /**
  311. * Returns user login by its payment ID
  312. *
  313. * @param $paymentID
  314. *
  315. * @return mixed|string
  316. */
  317. public static function getUserLoginByPaymentID($paymentID) {
  318. $paymentID = mysql_real_escape_string($paymentID);
  319. $query = "SELECT `realid` FROM `op_customers` WHERE `virtualid`='" . $paymentID . "'";
  320. $result = simple_query($query);
  321. $result = empty($result) ? '' : $result['realid'];
  322. return ($result);
  323. }
  324. /**
  325. * Returns user payment ID by its login
  326. *
  327. * @param $userLogin
  328. *
  329. * @return mixed|string
  330. */
  331. public static function getUserPaymentIDByLogin($userLogin) {
  332. $userLogin = mysql_real_escape_string($userLogin);
  333. $query = "SELECT `virtualid` FROM `op_customers` WHERE `realid`='" . $userLogin . "'";
  334. $result = simple_query($query);
  335. $result = empty($result) ? '' : $result['virtualid'];
  336. return ($result);
  337. }
  338. /**
  339. * Returns user stargazer data by login
  340. *
  341. * @param string $userLogin existing stargazer login
  342. *
  343. * @return array
  344. */
  345. public static function getUserStargazerData($userLogin) {
  346. $userLogin = mysql_real_escape_string($userLogin);
  347. $query = "SELECT * FROM `users` WHERE `login`='" . $userLogin . "';";
  348. $result = simple_query($query);
  349. return ($result);
  350. }
  351. /**
  352. * Returns array of available or filtered by user login RealNames as login => realname
  353. *
  354. * @param string $userLogin
  355. *
  356. * @return array|string
  357. */
  358. public static function getUserRealnames($userLogin = '') {
  359. $result = array();
  360. $whereStr = (empty($userLogin) ? '' : " WHERE `login` = '" . $userLogin . "'");
  361. $query = "SELECT * FROM `realname`" . $whereStr;
  362. $realnames = simple_queryall($query);
  363. if (!empty($realnames)) {
  364. foreach ($realnames as $io => $each) {
  365. $result[$each['login']] = $each['realname'];
  366. }
  367. }
  368. if (!empty($userLogin)) {
  369. if (empty($result[$userLogin])) {
  370. $result = '';
  371. } else {
  372. $result = $result[$userLogin];
  373. }
  374. }
  375. return($result);
  376. }
  377. /**
  378. * Returns array of user's cellphones
  379. *
  380. * @param $userLogin
  381. * @param $includeExtMobiles
  382. *
  383. * @return array
  384. */
  385. public static function getUserCellPhone($userLogin = '', $includeExtMobiles = false) {
  386. $result = array();
  387. $query = 'select `login`, `mobile` from `phones`';
  388. $whereStr = (empty($userLogin) ? '' : ' where `login` = "' . $userLogin . '"');
  389. if ($includeExtMobiles) {
  390. $query = 'select `phones`.`login`, `phones`.`mobile`, `mobileext`.`mobile` as `extmobile` ' .
  391. 'from `phones` ' .
  392. 'left join `mobileext` on `phones`.`login` = `mobileext`.`login` ';
  393. }
  394. $query.= $whereStr;
  395. $queryResult = simple_queryall($query);
  396. if (!empty($queryResult)) {
  397. foreach ($queryResult as $io => $eachRec) {
  398. if (!empty($eachRec['mobile'])) {
  399. $result[$eachRec['login']][] = $eachRec['mobile'];
  400. }
  401. if (!empty($eachRec['extmobile'])) {
  402. $result[$eachRec['login']][] = $eachRec['extmobile'];
  403. }
  404. }
  405. }
  406. return($result);
  407. }
  408. /**
  409. * Returns array of available or filtered by user login addresses as login => address
  410. *
  411. * @param string $userLogin
  412. * @param bool $addressCityDisplay
  413. *
  414. * @return array|string
  415. */
  416. public static function getUserAddresses($userLogin = '', $addressCityDisplay = false) {
  417. $result = array();
  418. $whereStr = (empty($userLogin) ? '' : " WHERE `address`.`login` = '" . $userLogin . "'");
  419. $query = "
  420. SELECT `address`.`login`,`city`.`cityname`,`street`.`streetname`,`build`.`buildnum`,`apt`.`apt`
  421. FROM `address`
  422. INNER JOIN `apt` ON `address`.`aptid`= `apt`.`id`
  423. INNER JOIN `build` ON `apt`.`buildid`=`build`.`id`
  424. INNER JOIN `street` ON `build`.`streetid`=`street`.`id`
  425. INNER JOIN `city` ON `street`.`cityid`=`city`.`id`"
  426. . $whereStr;
  427. $addresses = simple_queryall($query);
  428. if (!empty($addresses)) {
  429. foreach ($addresses as $eachAddress) {
  430. // zero apt handle
  431. $apartment_filtered = ($eachAddress['apt'] == 0) ? '' : '/' . $eachAddress['apt'];
  432. if ($addressCityDisplay) {
  433. $result[$eachAddress['login']] = $eachAddress['cityname'] . ' ' . $eachAddress['streetname'] . ' ' . $eachAddress['buildnum'] . $apartment_filtered;
  434. } else {
  435. $result[$eachAddress['login']] = $eachAddress['streetname'] . ' ' . $eachAddress['buildnum'] . $apartment_filtered;
  436. }
  437. }
  438. }
  439. if (!empty($userLogin)) {
  440. if (empty($result[$userLogin])) {
  441. $result = '';
  442. } else {
  443. $result = $result[$userLogin];
  444. }
  445. }
  446. return($result);
  447. }
  448. /**
  449. * Returns all tariff prices array
  450. *
  451. * @return array
  452. */
  453. public static function getTariffPriceAll($userTariffName = '') {
  454. $whereStr = (empty($userTariffName) ? '' : ' where `name` = "' . $userTariffName .'"');
  455. $query = 'select `name`, `Fee` from `tariffs`' . $whereStr;
  456. $queryResult = simple_queryall($query);
  457. $result = array();
  458. if (!empty($queryResult)) {
  459. foreach ($queryResult as $io => $eachTariff) {
  460. $result[$eachTariff['name']] = $eachTariff['Fee'];
  461. }
  462. }
  463. return ($result);
  464. }
  465. /**
  466. * Returns transaction data from "op_transactions", if it exists
  467. * May be used for checking transaction hash for duplicates
  468. *
  469. * @param string $transactHash
  470. *
  471. * @return array
  472. */
  473. public static function getOPTransactDataByHash($transactHash) {
  474. $result = array();
  475. if (!empty($transactHash)) {
  476. $transactData = simple_query('select * from `' . self::OP_TRANSACT_TABLE . '` where `hash` = "' . $transactHash . '"');
  477. if (!empty($transactData)) {
  478. $result = $transactData;
  479. }
  480. }
  481. return($result);
  482. }
  483. /**
  484. * Checks is transaction already exists or not?
  485. *
  486. * @param string $transactID
  487. *
  488. * @return bool
  489. */
  490. public static function checkTransactFileExists($transactID, $transactDirectory = self::PATH_TRANSACTS) {
  491. $result = (!empty($transactID) and file_exists(rtrim($transactDirectory, '/') . '/' . $transactID));
  492. return($result);
  493. }
  494. /**
  495. * Returns transaction data by $transactID
  496. *
  497. * @param $transactID
  498. *
  499. * @return mixed|string
  500. */
  501. public static function getTransactFileData($transactID, $transactDirectory = self::PATH_TRANSACTS) {
  502. $result = '';
  503. if (self::checkTransactFileExists($transactID, $transactDirectory = self::PATH_TRANSACTS)) {
  504. $result = unserialize(file_get_contents(rtrim($transactDirectory, '/') . '/' . $transactID));
  505. }
  506. return($result);
  507. }
  508. /**
  509. * Saves serialized transaction id to a specified directory
  510. *
  511. * @param string $transactID
  512. *
  513. * @return string
  514. */
  515. protected function saveTransactFile($transactID, $transactData, $transactDirectory = self::PATH_TRANSACTS) {
  516. $result = file_put_contents(rtrim($transactDirectory, '/') . '/' . $transactID, serialize($transactData));
  517. return($result);
  518. }
  519. /**
  520. * Returns transaction data from DB by $transactID
  521. *
  522. * @param string $transactID
  523. * @param string $tableName
  524. * @param string $searchFieldName
  525. *
  526. * @return mixed|string
  527. */
  528. public static function getTransactDataDB($transactID, $tableName, $searchFieldName) {
  529. $result = '';
  530. $tQuery = "SELECT * FROM `' . $tableName . '` WHERE `' . $searchFieldName . '` = '" . $transactID . "' ";
  531. $result = simple_query($tQuery);
  532. return($result);
  533. }
  534. /**
  535. * Saves transaction data to a dedicated for a certain paysys DB table
  536. *
  537. * NEEDS TO BE OVERRIDDEN
  538. *
  539. * @return void
  540. */
  541. protected function saveTransactDataDB($tableName = '', $transactData = '') {
  542. //todo: place your transaction to DB saving code here
  543. }
  544. /**
  545. * Returns current UNIX timestamp in milliseconds (13 digits)
  546. *
  547. * @return int
  548. */
  549. public static function getUnixTimestampMillisec() {
  550. $now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
  551. $now_ms = (int)$now->format('Uv');
  552. return ($now_ms);
  553. }
  554. /**
  555. * Checks if payment sum is a number with no more than $maxDecimals decimal places
  556. * and with a dot as decimal delimiter
  557. *
  558. * @param $paysum
  559. *
  560. * @return bool
  561. */
  562. public static function checkPaySumCorrect($paysum, $maxDecimals = 2) {
  563. $paysum = str_ireplace(array('"', "'"), '', trim($paysum));
  564. $regex = '/^\d+(\.[0-9]{1,' . $maxDecimals . '}(0*))?$/';
  565. return (preg_match($regex, $paysum) === 1);
  566. }
  567. /**
  568. * Returns random numeric string, which will be used as unique transaction hash
  569. *
  570. * @param int $size
  571. *
  572. * @return string
  573. */
  574. public static function genRandNumString($size = 12) {
  575. $characters = '0123456789';
  576. $string = "";
  577. for ($p = 0; $p < $size; $p++) {
  578. $string.= $characters[mt_rand(0, (strlen($characters) - 1))];
  579. }
  580. return ($string);
  581. }
  582. /**
  583. * Encode a string with URL-safe Base64.
  584. *
  585. * @param string $input The string you want encoded
  586. *
  587. * @return string The base64 encode of what you passed in
  588. */
  589. public static function urlSafeBase64Encode($input, $EqualSignRemove = true) {
  590. $result = ($EqualSignRemove)
  591. ? str_replace('=', '', strtr(base64_encode($input), '+/', '-_'))
  592. : strtr(base64_encode($input), '+/', '-_');
  593. return ($result);
  594. }
  595. /**
  596. * Decode a string with URL-safe Base64.
  597. *
  598. * @param string $input A Base64 encoded string
  599. *
  600. * @return string A decoded string
  601. */
  602. public static function urlSafeBase64Decode($input) {
  603. $remainder = strlen($input) % 4;
  604. if ($remainder) {
  605. $padlen = 4 - $remainder;
  606. $input.= str_repeat('=', $padlen);
  607. }
  608. return (base64_decode(strtr($input, '-_', '+/')));
  609. }
  610. /**
  611. * Writes some debugging to a file with a timestamp for each line and an "\n" after each line
  612. *
  613. * @param string $logmsg
  614. * @param bool $debugModeON
  615. * @param string $filePath
  616. *
  617. * @return void
  618. */
  619. public static function writeDebugLog($logmsg, $debugModeON = true, $newlinesPrependCnt = 0, $filePath = '') {
  620. if ($debugModeON) {
  621. $filePath = empty($filePath) ? self::PATH_DEBUGLOG : $filePath;
  622. $ident4spcs = str_repeat(' ', 4);
  623. $newlinesPrepend = str_repeat("\n", $newlinesPrependCnt);
  624. file_put_contents($filePath, $newlinesPrepend . curdatetime() . $ident4spcs . $logmsg . "\n", FILE_APPEND);
  625. }
  626. }
  627. /**
  628. * Intended to spit out erroneous replies
  629. *
  630. * MIGHT BE OVERRIDDEN
  631. *
  632. * @param $errorCode
  633. * @param $errorMsg
  634. *
  635. * @return false|string|void
  636. */
  637. protected function replyError($errorCode = '', $errorMsg = '') {
  638. //todo: override with your error replying code here, if needed
  639. header('HTTP/1.1 ' . $errorCode . ' ' . $errorMsg . '"', true, $errorCode);
  640. die($errorCode . ' - ' . $errorMsg);
  641. }
  642. /**
  643. * Requests processing routine
  644. *
  645. * NEEDS TO BE OVERRIDDEN
  646. *
  647. * @return void
  648. */
  649. protected function processRequests() {
  650. // todo: Your requests processing code here
  651. }
  652. /**
  653. * Listen to your heart when he's calling for you
  654. * Listen to your heart, there's nothing else you can do
  655. *
  656. * NEEDS TO BE OVERRIDDEN
  657. *
  658. * @return void
  659. */
  660. protected function listen() {
  661. //todo: Place your "listening" code here
  662. }
  663. }