lightninginit.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. <?php
  2. class Lightning {
  3. /**
  4. * Threshold of calls after caching will be used
  5. *
  6. * @var int
  7. */
  8. protected $massThreshold = 10;
  9. /**
  10. * User data caching timeout in seconds
  11. *
  12. * @var int
  13. */
  14. protected $cachingTimeout = 60;
  15. /**
  16. * Summary count of calls on current minute
  17. *
  18. * @var int
  19. */
  20. protected $startsCount = 0;
  21. /**
  22. * Memcached object placeholder
  23. *
  24. * @var object
  25. */
  26. protected $memcached = '';
  27. /**
  28. * default memcached server IP
  29. *
  30. * @var string
  31. */
  32. protected $memcachedServer = '127.0.0.1';
  33. /**
  34. * default memcached server port
  35. *
  36. * @var type
  37. */
  38. protected $memcachedPort = 11211;
  39. /**
  40. * Massive user initialization flag
  41. *
  42. * @var bool
  43. */
  44. protected $massrun = false;
  45. /**
  46. * Contains all users data array
  47. *
  48. * @var array
  49. */
  50. protected $allUserData = array();
  51. /**
  52. * Predefined constants, etc..
  53. */
  54. const CACHE_PREFIX = 'LINIT_';
  55. const MASS_KEY = 'MASSRUNCOUNT';
  56. const USERDATA = 'LIGHTNING_DATA';
  57. const MAC = 'MAC_';
  58. const SPEED = 'SPEED_';
  59. const SPEEDUP = 'SPEEDUP_';
  60. public function __construct() {
  61. $this->initMemcached();
  62. $this->detectMassRun();
  63. $this->loadCacheData();
  64. }
  65. /**
  66. * Inits memcached object for further usage
  67. *
  68. * @return void
  69. */
  70. protected function initMemcached() {
  71. $this->memcached = new Memcached();
  72. $this->memcached->addServer($this->memcachedServer, $this->memcachedPort);
  73. }
  74. /**
  75. * Generates key storable internal name
  76. *
  77. * @param string $key
  78. *
  79. * @return string
  80. */
  81. protected function genCacheKey($key) {
  82. $result = self::CACHE_PREFIX . $key;
  83. return ($result);
  84. }
  85. /**
  86. * Returns data by key name. Empty if no data exists or cache expired.
  87. *
  88. * @param string $key Storage key name
  89. * @param int $expiration Expiration time in seconds
  90. *
  91. * @return mixed
  92. */
  93. protected function getCache($key, $expiration = 2592000) {
  94. $result = '';
  95. $keyRaw = $key;
  96. $key = $this->genCacheKey($key);
  97. $result = $this->memcached->get($key);
  98. if (!$result) {
  99. $result = '';
  100. }
  101. return ($result);
  102. }
  103. /**
  104. * Puts data into cache storage
  105. *
  106. * @param string $key
  107. * @param string $data
  108. * @param int $expiration
  109. *
  110. * @return void
  111. */
  112. protected function setCache($key, $data, $expiration = 2592000) {
  113. $key = $this->genCacheKey($key);
  114. // Set expiration time not more 1 month
  115. $expiration = ($expiration > 2592000) ? '2592000' : $expiration;
  116. $this->memcached->set($key, $data, $expiration);
  117. }
  118. /**
  119. * Detects massive user init. Sets specific flag for the instance.
  120. *
  121. * @return void
  122. */
  123. protected function detectMassRun() {
  124. $currentMinute = date("H:i");
  125. $this->startsCount = $this->getCache(self::MASS_KEY . $currentMinute, $this->cachingTimeout);
  126. if (empty($this->startsCount)) {
  127. $this->startsCount=0;
  128. }
  129. $this->startsCount++;
  130. if ($this->startsCount >= $this->massThreshold) {
  131. $this->massrun = true;
  132. }
  133. $this->setCache(self::MASS_KEY . $currentMinute, $this->startsCount, $this->cachingTimeout);
  134. }
  135. /**
  136. * Preloads all users data on mass-run detected and stores it in cache
  137. *
  138. * @return void
  139. */
  140. protected function loadCacheData() {
  141. if ($this->massrun) {
  142. $this->allUserData = $this->getCache(self::USERDATA, $this->cachingTimeout);
  143. if (empty($this->allUserData)) {
  144. $config = parse_ini_file(dirname(__FILE__) . "/config");
  145. $dbport = (empty($config['port'])) ? 3306 : $config['port'];
  146. $loginDB = new mysqli($config['host'], $config['username'], $config['password'], $config['database'], $dbport);
  147. $resultTmp = array();
  148. $queryUsers = "SELECT `login`,`IP`,`Tariff` from `users`";
  149. $usersRaw = $loginDB->query($queryUsers);
  150. if (!empty($usersRaw)) {
  151. while ($eachLine = mysqli_fetch_assoc($usersRaw)) {
  152. if (!empty($eachLine)) {
  153. $resultTmp[$eachLine['login']]['IP'] = $eachLine['IP'];
  154. $resultTmp[$eachLine['login']]['Tariff'] = $eachLine['Tariff'];
  155. $resultTmp[$eachLine['login']]['mac'] = '';
  156. $resultTmp[$eachLine['login']]['speeddown'] = '';
  157. $resultTmp[$eachLine['login']]['speedup'] = '';
  158. $resultTmp[$eachLine['login']]['speedoverride'] = '';
  159. }
  160. }
  161. $queryMac = "SELECT `ip`,`mac` FROM `nethosts`";
  162. $macTmp = array();
  163. $macRaw = $loginDB->query($queryMac);
  164. if (!empty($macRaw)) {
  165. while ($eachLine = mysqli_fetch_assoc($macRaw)) {
  166. $macTmp[$eachLine['ip']] = $eachLine['mac'];
  167. }
  168. }
  169. $queryTariffSpeeds = "SELECT `tariff`,`speeddown`,`speedup` from `speeds`";
  170. $tariffSpeedsRaw = $loginDB->query($queryTariffSpeeds);
  171. $tariffSpeedsTmp = array();
  172. if (!empty($tariffSpeedsRaw)) {
  173. while ($eachLine = mysqli_fetch_assoc($tariffSpeedsRaw)) {
  174. $tariffSpeedsTmp[$eachLine['tariff']]['speeddown'] = $eachLine['speeddown'];
  175. $tariffSpeedsTmp[$eachLine['tariff']]['speedup'] = $eachLine['speedup'];
  176. }
  177. }
  178. $querySpeedOverrides = "SELECT `login`,`speed` FROM `userspeeds` WHERE `speed`!='0'";
  179. $speedOverridesRaw = $loginDB->query($querySpeedOverrides);
  180. $speedOverridesTmp = array();
  181. if (!empty($speedOverridesRaw)) {
  182. while ($eachLine = mysqli_fetch_assoc($speedOverridesRaw)) {
  183. $speedOverridesTmp[$eachLine['login']] = $eachLine['speed'];
  184. }
  185. }
  186. //building final result
  187. foreach ($resultTmp as $eachLogin => $eachData) {
  188. $userTariff = $eachData['Tariff'];
  189. if (isset($macTmp[$eachData['IP']])) {
  190. $userMac = $macTmp[$eachData['IP']];
  191. $resultTmp[$eachLogin]['mac'] = $userMac;
  192. $this->setCache(self::MAC . $eachLogin, $userMac, $this->cachingTimeout);
  193. }
  194. if (isset($tariffSpeedsTmp[$userTariff])) {
  195. $speedDown = $tariffSpeedsTmp[$userTariff]['speeddown'];
  196. $speedUp = $tariffSpeedsTmp[$userTariff]['speedup'];
  197. $resultTmp[$eachLogin]['speeddown'] = $speedDown;
  198. $resultTmp[$eachLogin]['speedup'] = $speedUp;
  199. $this->setCache(self::SPEED . $eachLogin, $speedDown, $this->cachingTimeout);
  200. $this->setCache(self::SPEEDUP . $eachLogin, $speedUp, $this->cachingTimeout);
  201. }
  202. if (isset($speedOverridesTmp[$eachLogin])) {
  203. $userSpeedOverride = $speedOverridesTmp[$eachLogin];
  204. $resultTmp[$eachLogin]['speedoverride'] = $userSpeedOverride;
  205. $this->setCache(self::SPEED . $eachLogin, $userSpeedOverride, $this->cachingTimeout);
  206. $this->setCache(self::SPEEDUP . $eachLogin, $userSpeedOverride, $this->cachingTimeout);
  207. }
  208. }
  209. }
  210. $loginDB->close();
  211. $this->allUserData = $resultTmp;
  212. $this->setCache('LIGHTNING_DATA', $this->allUserData, $this->cachingTimeout);
  213. }
  214. }
  215. }
  216. /**
  217. * Runs separate database query
  218. *
  219. * @param string $query
  220. *
  221. * @return array
  222. */
  223. protected function runQuery($query) {
  224. $result = array();
  225. $config = parse_ini_file(dirname(__FILE__) . "/config");
  226. $dbport = (empty($config['port'])) ? 3306 : $config['port'];
  227. $loginDB = new mysqli($config['host'], $config['username'], $config['password'], $config['database'], $dbport);
  228. $rawData = $loginDB->query($query);
  229. if (!empty($rawData)) {
  230. while ($eachLine = mysqli_fetch_assoc($rawData)) {
  231. $result[] = $eachLine;
  232. }
  233. }
  234. $loginDB->close();
  235. return($result);
  236. }
  237. /**
  238. * Returns user MAC
  239. *
  240. * @param string $login
  241. *
  242. * @return string
  243. */
  244. public function getMac($login) {
  245. $result = '';
  246. if (isset($this->allUserData[$login])) {
  247. $result = $this->allUserData[$login]['mac'];
  248. } else {
  249. $query = "SELECT `nethosts`.`mac` FROM `users` INNER JOIN `nethosts` USING (`ip`) WHERE `users`.`login`='" . $login . "'";
  250. $resultTmp = $this->runQuery($query);
  251. if (isset($resultTmp[0]['mac'])) {
  252. $result = $resultTmp[0]['mac'];
  253. }
  254. }
  255. return($result);
  256. }
  257. /**
  258. * Returns user download speed
  259. *
  260. * @param string $login
  261. *
  262. * @return string
  263. */
  264. public function getSpeed($login) {
  265. $result = '';
  266. if (isset($this->allUserData[$login])) {
  267. if (empty($this->allUserData[$login]['speedoverride'])) {
  268. $result = $this->allUserData[$login]['speeddown'];
  269. } else {
  270. $result = $this->allUserData[$login]['speedoverride'];
  271. }
  272. } else {
  273. $query = "SELECT `speed` FROM `userspeeds` where `login`='" . $login . "';";
  274. $speedOverride = $this->runQuery($query);
  275. if (!empty($speedOverride)) {
  276. $override = $speedOverride[0]['speed'];
  277. }
  278. if (empty($override)) {
  279. $query = "SELECT `speeddown` from `speeds` INNER JOIN (SELECT `Tariff` FROM users WHERE `login`='" . $login . "') AS t_u USING (`Tariff`)";
  280. $tariffSpeed = $this->runQuery($query);
  281. if (isset($tariffSpeed[0])) {
  282. $result = $tariffSpeed[0]['speeddown'];
  283. }
  284. } else {
  285. $result = $override;
  286. }
  287. }
  288. return($result);
  289. }
  290. /**
  291. * Returns user upload speed
  292. *
  293. * @param string $login
  294. *
  295. * @return string
  296. */
  297. public function getSpeedUp($login) {
  298. $result = '';
  299. if (isset($this->allUserData[$login])) {
  300. if (empty($this->allUserData[$login]['speedoverride'])) {
  301. $result = $this->allUserData[$login]['speedup'];
  302. } else {
  303. $result = $this->allUserData[$login]['speedoverride'];
  304. }
  305. } else {
  306. $query = "SELECT `speed` FROM `userspeeds` where `login`='" . $login . "';";
  307. $speedOverride = $this->runQuery($query);
  308. if (!empty($speedOverride)) {
  309. $override = $speedOverride[0]['speed'];
  310. }
  311. if (empty($override)) {
  312. $query = "SELECT `speedup` from `speeds` INNER JOIN (SELECT `Tariff` FROM users WHERE `login`='" . $login . "') AS t_u USING (`Tariff`)";
  313. $tariffSpeed = $this->runQuery($query);
  314. if (isset($tariffSpeed[0])) {
  315. $result = $tariffSpeed[0]['speedup'];
  316. }
  317. } else {
  318. $result = $override;
  319. }
  320. }
  321. return($result);
  322. }
  323. }