/engine/functions/classes/class_cron.php

https://github.com/Pankrashingo/cms-landing · PHP · 4032 lines · 3041 code · 683 blank · 308 comment · 344 complexity · e1d46bcdf34e2989a208985fe1fd66c9 MD5 · raw file

Large files are truncated click here to view the full file

  1. <?php
  2. include_once(__ENGINE_PATH.'/functions/subfunctions/file_functions.php');
  3. class Cron
  4. {
  5. protected $db;
  6. public function __construct(&$db)
  7. {
  8. $this->db=&$db;
  9. }
  10. /**
  11. * Блок функций для контроля исполнения cron
  12. */
  13. /**
  14. * Запись в базу в момент запуска крона
  15. * @param $name
  16. * @param $interval
  17. * @return int OR false
  18. */
  19. public function cron_start($name, $interval){
  20. $sql="INSERT INTO `cron_report` (`name`,`interval`,`starttime`) VALUES('{$name}', {$interval}, NOW())";
  21. if(!$this->db->query($sql)) {
  22. $this->cron_bugreport("Ошибка старта крон-задания: {$name}.");
  23. return false;
  24. }
  25. return $this->db->get_insert_id();
  26. }
  27. /**
  28. * Промежуточное обновления крон отчёта
  29. * @param $id
  30. * @param $data
  31. * @return bool
  32. */
  33. public function cron_update_report($id, $data){
  34. $sql="UPDATE `cron_report` SET `report_data`='{$data}' WHERE `id`={$id}";
  35. if(!$this->db->query($sql)) return false;
  36. return true;
  37. }
  38. /**
  39. * Получить время последнего выполнения крона по name
  40. * @param $name
  41. * @return datetime OR false
  42. */
  43. public function get_last_runtime($name){
  44. $sql = "SELECT `starttime` FROM `cron_report` WHERE `name`='{$name}' ORDER BY `id` DESC LIMIT 1";
  45. $this->db->query($sql);
  46. $result = $this->db->get_result();
  47. if(count($result)){
  48. return $result[0]['starttime'];
  49. }
  50. return false;
  51. }
  52. /**
  53. *
  54. * Крон завершен - обновить отчёт
  55. * @param $id
  56. * @param $data
  57. * @return bool
  58. */
  59. public function cron_stop($id, $data){
  60. $sql="UPDATE `cron_report` SET `stoptime`=NOW(), `report_data`='{$data}' WHERE `id`={$id}";
  61. if(!$this->db->query($sql)) {
  62. $this->cron_bugreport("Ошибка остановки крон-задания: #{$id}.");
  63. file_put_contents(__LOG_ERROR_PATH.'/cronstop.txt',gmdate('d-m-Y H:i')."SQL: {$sql}, ID: {$id}\n",FILE_APPEND);
  64. return false;
  65. }
  66. return true;
  67. }
  68. /**
  69. * Отправка ошибки админу
  70. * @param $msg
  71. */
  72. public function cron_bugreport($msg){
  73. include_once(__ENGINE_PATH.'/functions/classes/class_mailer.php');
  74. $mailer=new Mailer();
  75. $mailer->mail(__SUPPORT_EMAIL, 'Багрепорт: ошибка при выполнении cron-задачи', $msg);
  76. }
  77. /**
  78. * Список отчётов
  79. * @param string $where
  80. * @return array
  81. */
  82. public function cron_get_reports($where = ''){
  83. $sql = "SELECT * FROM `cron_report`";
  84. if(strlen($where)) $sql .= " WHERE {$where}";
  85. $sql .= " ORDER BY `id` DESC";
  86. $this->db->query($sql);
  87. return $this->db->get_result();
  88. }
  89. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  90. //add remined event to write review
  91. public function remind_users_make_reviews(){
  92. $func_report = array("users_count"=>0, "guest_count"=>0);
  93. $users_no_visits = array();//юзеры, которые возможно долго не заходили на сайт и получается, что не видили первое оповещение(спустя 4 дня)
  94. $user_timetables = array();
  95. $sql="SELECT DISTINCTROW UNIX_TIMESTAMP(t.`date`) as `date`,t.`id` as `timetable_id`,t.`date_text`,a.`id` as `action_id`,a.`type`, a.`alias` as `action_link`, a.`name` as `action_name`,o.`user_id`
  96. FROM `timetable_orders` o force index (`user_id_type`)
  97. INNER JOIN `timetable` t ON o.`timetable_id`=t.`id`
  98. INNER JOIN `actions` a ON t.`action_id`=a.`id`
  99. LEFT JOIN `reviews` r ON r.`user_id`=o.`user_id` AND r.`object_type`=3 AND r.`object_id`=a.`id`
  100. WHERE o.`type`<3 AND
  101. o.`user_id`>0 AND
  102. r.`id` is NULL AND
  103. (
  104. (a.`type` NOT IN(2,3,6) AND (DATE(t.`date`)=DATE(NOW()-INTERVAL 4 DAY) OR DATE(t.`date`)=DATE(NOW()-INTERVAL 14 DAY)) )
  105. OR
  106. (a.`type` IN(2,3) AND DATE(o.`date`)=DATE(NOW()-INTERVAL 14 DAY))
  107. ) AND
  108. o.`user_id`!=a.`owner_id`
  109. ORDER BY o.`user_id`";
  110. $this->db->query($sql);
  111. $result=$this->db->get_result();
  112. if(count($result)){
  113. include_once(__ENGINE_PATH.'/functions/classes/class_eventer.php');
  114. $eventer=new Eventer($this->db);
  115. foreach($result as $item){
  116. //записываем id юзеров, чтобы проверить дату последнего визита сайта
  117. if(gmdate("d", $item["date"]) === gmdate("d", (time()-14*24*3600)) || in_array($item["type"], array(2,3,6))){
  118. $users_no_visits[] = $item["user_id"];
  119. $user_timetables[$item["user_id"]][] = array("action_link"=>$item["action_link"],"action_name"=>$item["action_name"],"timetable_id"=>$item["timetable_id"]);
  120. }
  121. $eventer->add_event(1,10,array($item['user_id']=>$item['user_id']),0,$item['action_id'],3,$item['timetable_id'],6,'',gmdate("Y-m-d",time()));
  122. }
  123. }
  124. //теперь проверим дату последнего посещения
  125. if(count($users_no_visits)){
  126. $sql="SELECT MAX(v.`date`) as `date`, v.`user_id`,u.`email`,u.`name`
  127. FROM `visits` v
  128. JOIN `users` u ON u.`id`=v.`user_id`
  129. WHERE
  130. v.`user_id` IN (".join(", ", $users_no_visits).")
  131. GROUP BY
  132. v.`user_id`
  133. HAVING
  134. MAX( v.`date`) <= (NOW()-INTERVAL 10 DAY)
  135. ORDER BY
  136. v.`date` DESC
  137. ";
  138. $this->db->query($sql);
  139. $result3=$this->db->get_result();
  140. if(count($result3)){
  141. global $object_types;
  142. include_once(__ENGINE_PATH.'/functions/classes/class_mailer.php');
  143. $mailer = new Mailer();
  144. foreach($result3 as $value){
  145. if(!trim($value["email"]))
  146. continue;
  147. foreach($user_timetables[$value["user_id"]] as $timetable_data){
  148. $msg = "";
  149. $subject = "";
  150. $action_link="/".$object_types[3]['url']."/".$timetable_data["action_link"]."/".($timetable_data["timetable_id"] ? "?date=".$timetable_data["timetable_id"] : "");
  151. $action_name=$timetable_data["action_name"];
  152. $user_name=$value["name"];
  153. include(__ENGINE_PATH."/templates/email.user_review_remind.php");
  154. if(@$mailer->mail($value["email"], $subject, $msg)) $func_report["users_count"] += 1;
  155. }
  156. }
  157. }
  158. }
  159. //напоминаем об отзыве гостям, подававшим заявку
  160. $sql = "
  161. SELECT
  162. t.`id` as `timetable_id`, a.`alias` as `action_link`, a.`name` as `action_name`, o.`email`, o.`name` as `guest_name`
  163. FROM `timetable_orders` o
  164. INNER JOIN `timetable` t ON o.`timetable_id`=t.`id`
  165. INNER JOIN `actions` a ON t.`action_id`=a.`id`
  166. WHERE
  167. o.`type`<3
  168. AND o.`user_id`=0
  169. AND o.`email` != ''
  170. AND (
  171. (a.`type` NOT IN(2,3,6) AND DATE(t.`date`)=DATE(NOW()-INTERVAL 4 DAY))
  172. OR
  173. (a.`type` IN(2,3) AND DATE(o.`date`)=DATE(NOW()-INTERVAL 14 DAY))
  174. )
  175. GROUP BY
  176. o.`order_id`
  177. ";
  178. $this->db->query($sql);
  179. $result2=$this->db->get_result();
  180. if(count($result2)){
  181. global $object_types;
  182. include_once(__ENGINE_PATH.'/functions/classes/class_mailer.php');
  183. $mailer = new Mailer();
  184. foreach($result2 as $value){
  185. if(!trim($value["email"]))
  186. continue;
  187. $msg = "";
  188. $subject = "";
  189. $action_link="/".$object_types[3]['url']."/".$value["action_link"]."/".($value["timetable_id"] ? "?date=".$value["timetable_id"] : "");
  190. $action_name=$value["action_name"];
  191. $guest_name=$value["guest_name"];
  192. include(__ENGINE_PATH."/templates/email.guest_review_remind.php");
  193. if(@$mailer->mail($value["email"], $subject, $msg)) $func_report["guest_count"] += 1;
  194. }
  195. }
  196. return "пользователям отправлено писем - ".$func_report["users_count"].", гостям отправлено писем - ".$func_report["guest_count"];
  197. }
  198. //send reminder to check actual information to object`s owners
  199. public function actuality_broodcast($actuality_days=180)
  200. {
  201. $mail_count=0;
  202. $sql='';
  203. global $object_types;
  204. $result=array();
  205. foreach($object_types as $key=>$object_type)
  206. {
  207. if(in_array($key,array(2,3,6,7,8,12,13,14)))continue;
  208. elseif($key==1){
  209. $sql="SELECT UNIX_TIMESTAMP(o.`created`) as `created`,o.`id`,u.`email`,u.`login`,u.`name` as `user_name`,u.`surname` ,COALESCE(h.`action_type`,0) as `action_type`, DATEDIFF( NOW(), MAX(COALESCE(h.`date`,o.`created`) )) AS `exist` ,o.`owner_id`,o.`name`,o.`alias`,{$key} as `object_type`, 0 as `type`, obr.`region`, obr.`id_object_regions`
  210. FROM `{$object_type['class']}` o
  211. LEFT JOIN `users` u ON o.`owner_id`=u.`id`
  212. LEFT JOIN `object_regions` obr ON obr.`object_type` IN(1,5) AND obr.`object_id`=o.`id` AND obr.`main_link`=1
  213. LEFT JOIN `objects_history` h ON h.`object_id`=o.`id` AND h.`object_type`={$key} AND h.`action_type` IN(1,2,3) /*AND h.`user_id`=o.`owner_id`*/
  214. WHERE o.`moderated`=1 AND o.`block`=0 AND o.`is_treiner`=1 AND o.`owner_id`!=30 AND u.`group`=1
  215. GROUP BY o.`id`
  216. HAVING (DATEDIFF(NOW(), MAX(COALESCE(h.`date`,o.`created`)))>0) AND (DATEDIFF(NOW(), MAX(COALESCE(h.`date`,o.`created`)))%{$actuality_days})=0
  217. ORDER BY MAX(COALESCE(h.`date`,o.`created`)) ASC,`id_object_regions` ASC";
  218. $this->db->query($sql);
  219. $result=array_merge($result,$this->db->get_result());
  220. }elseif($key==5){
  221. $sql="SELECT UNIX_TIMESTAMP(o.`created`) as `created`,o.`id`,u.`email`,u.`login`,u.`name` as `user_name`,u.`surname` ,COALESCE(h.`action_type`,0) as `action_type`, DATEDIFF( NOW(), MAX(COALESCE(h.`date`,o.`created`) )) AS `exist` ,o.`owner_id`,o.`name`,o.`alias`,{$key} as `object_type`, 0 as `type`, obr.`region`, obr.`id_object_regions`
  222. FROM `{$object_type['class']}` o
  223. LEFT JOIN `users` u ON o.`owner_id`=u.`id`
  224. LEFT JOIN `object_regions` obr ON obr.`object_type` IN(1,5) AND obr.`object_id`=o.`id` AND obr.`main_link`=1
  225. LEFT JOIN `objects_history` h ON h.`object_id`=o.`id` AND h.`object_type`={$key} AND h.`action_type` IN(1,2,3) /*AND h.`user_id`=o.`owner_id`*/
  226. WHERE o.`moderated`=1 AND o.`block`=0 AND o.`is_treiner`=0 AND o.`is_consultant`=1 AND o.`owner_id`!=30 AND u.`group`=1
  227. GROUP BY o.`id`
  228. HAVING (DATEDIFF(NOW(), MAX(COALESCE(h.`date`,o.`created`)))>0) AND (DATEDIFF(NOW(), MAX(COALESCE(h.`date`,o.`created`)))%{$actuality_days})=0
  229. ORDER BY MAX(COALESCE(h.`date`,o.`created`)) ASC,`id_object_regions` ASC";
  230. $this->db->query($sql);
  231. $result=array_merge($result,$this->db->get_result());
  232. }elseif($key==9){
  233. include_once(__ENGINE_PATH."/functions/classes/class_esoterics.php");
  234. $esoterics=new Esoterics($this->db);
  235. foreach($esoterics->esoteric_type as $key2=>$type)
  236. {
  237. $sql="SELECT UNIX_TIMESTAMP(o.`created`) as `created`,o.`id`,u.`email`,u.`login`,u.`name` as `user_name`,u.`surname` ,COALESCE(h.`action_type`,0) as `action_type`, DATEDIFF( NOW(), MAX(COALESCE(h.`date`,o.`created`) )) AS `exist` ,o.`owner_id`,o.`name`,o.`alias`,9 as `object_type`, o.`type`, obr.`region`, obr.`id_object_regions`
  238. FROM `{$object_type['class']}` o
  239. LEFT JOIN `users` u ON o.`owner_id`=u.`id`
  240. LEFT JOIN `object_regions` obr ON obr.`object_type`={$key} AND obr.`object_id`=o.`id` AND obr.`main_link`=1
  241. LEFT JOIN `objects_history` h ON h.`object_id`=o.`id` AND h.`object_type`={$key} AND h.`action_type` IN(1,2,3) /*AND h.`user_id`=o.`owner_id`*/
  242. WHERE o.`moderated`=1 AND o.`block`=0 AND o.`type`={$key2} AND o.`owner_id`!=30 AND u.`group`=1
  243. GROUP BY o.`id`
  244. HAVING (DATEDIFF(NOW(), MAX(COALESCE(h.`date`,o.`created`)))>0) AND (DATEDIFF(NOW(), MAX(COALESCE(h.`date`,o.`created`)))%{$actuality_days})=0
  245. ORDER BY MAX(COALESCE(h.`date`,o.`created`)) ASC,`id_object_regions` ASC";
  246. $this->db->query($sql);
  247. $result=array_merge($result,$this->db->get_result());
  248. }
  249. }elseif($key!=12){
  250. $sql="SELECT UNIX_TIMESTAMP(o.`created`) as `created`,o.`id`,u.`email`,u.`login`,u.`name` as `user_name`,u.`surname` ,COALESCE(h.`action_type`,0) as `action_type`, DATEDIFF( NOW(), MAX(COALESCE(h.`date`,o.`created`) )) AS `exist` ,o.`owner_id`,o.`name`,o.`alias`,{$key} as `object_type`, 0 as `type`, obr.`region`, obr.`id_object_regions`
  251. FROM `{$object_type['class']}` o
  252. LEFT JOIN `users` u ON o.`owner_id`=u.`id`
  253. LEFT JOIN `object_regions` obr ON obr.`object_type`={$key} AND obr.`object_id`=o.`id` AND obr.`main_link`=1
  254. LEFT JOIN `objects_history` h ON h.`object_id`=o.`id` AND h.`object_type`={$key} AND h.`action_type` IN(1,2,3) /*AND h.`user_id`=o.`owner_id`*/
  255. WHERE o.`moderated`=1 AND o.`block`=0 AND o.`owner_id`!=30 AND u.`group`=1
  256. GROUP BY o.`id`
  257. HAVING (DATEDIFF(NOW(), MAX(COALESCE(h.`date`,o.`created`)))>0) AND (DATEDIFF(NOW(), MAX(COALESCE(h.`date`,o.`created`)))%{$actuality_days})=0
  258. ORDER BY MAX(COALESCE(h.`date`,o.`created`)) ASC,`id_object_regions` ASC";
  259. $this->db->query($sql);
  260. $result=array_merge($result,$this->db->get_result());
  261. }else{
  262. $sql="SELECT UNIX_TIMESTAMP(o.`created`) as `created`,o.`id`,u.`email`,u.`login`,u.`name` as `user_name`,u.`surname` ,COALESCE(h.`action_type`,0) as `action_type`, DATEDIFF( NOW() , MAX(COALESCE(h.`date`,o.`created`) )) AS `exist` ,o.`owner_id`,o.`name`,o.`alias`,{$key} as `object_type`, 0 as `type`, 0 as `region`, 0 as `id_object_regions`
  263. FROM `{$object_type['class']}` o
  264. LEFT JOIN `users` u ON o.`owner_id`=u.`id`
  265. LEFT JOIN `objects_history` h ON h.`object_id`=o.`id` AND h.`object_type`={$key} AND h.`action_type` IN(1,2,3) /*AND h.`user_id`=o.`owner_id`*/
  266. WHERE o.`moderated`=1 AND o.`block`=0 AND o.`owner_id`!=30 AND u.`group`=1
  267. GROUP BY o.`id`
  268. HAVING (DATEDIFF(NOW(), MAX(COALESCE(h.`date`,o.`created`)))>0) AND (DATEDIFF(NOW(), MAX(COALESCE(h.`date`,o.`created`)))%{$actuality_days})=0
  269. ORDER BY MAX(COALESCE(h.`date`,o.`created`)) ASC";
  270. $this->db->query($sql);
  271. $result=array_merge($result,$this->db->get_result());
  272. }
  273. }
  274. $user_objects=array();
  275. global $new_region_codes;
  276. foreach($result as $item){
  277. if(!in_array($item['object_type'],array(9,12))){
  278. if($item['region']>0 && !in_array($item['object_type'],array(3,7,13))) $link='/'.$new_region_codes[$item['region']]['code'].'/'.$object_types[$item['object_type']]['url'].'/'.$item['alias'];
  279. else $link='/'.$object_types[$item['object_type']]['url'].'/'.$item['alias'];
  280. }elseif($item['object_type']!=12) $link='/'.$new_region_codes[$item['region']]['code'].'/'.$object_types[$item['object_type']]['url'.$item['type']].'/'.$item['alias'];
  281. else $link='/'.$object_types[$item['object_type']]['url'].'/';
  282. $user_objects[$item['owner_id']][0]=array('email'=>$item['email'],'login'=>$item['login'],'name'=>$item['user_name'],'surname'=>$item['surname']);
  283. if($item['object_type']==9) $item['object_type'].=$item['type'];
  284. $user_objects[$item['owner_id']][$item['object_type']][]=array('name'=>$item['name'],'alias'=>$item['alias'],'exist'=>$item['exist'],'link'=>$link,'type'=>$item['type'],'action_type'=>$item['action_type']);
  285. }
  286. if(count($user_objects)>0){
  287. include_once(__ENGINE_PATH.'/functions/classes/class_mailer.php');
  288. $mailer=new Mailer();
  289. foreach($user_objects as $item)
  290. {
  291. $subject='';
  292. $msg='';
  293. include(__ENGINE_PATH.'/templates/email.owners.broadcast.php');
  294. //echo $item[0]['email'].'<br/>'.$msg.'<br/><br/><br/>';
  295. if(!@$mailer->mail($item[0]['email'], $subject, $msg)) {
  296. trigger_error('Не удалось отправить напоминания о проверке актуальности объектов',E_USER_WARNING);
  297. }else $mail_count++;
  298. }
  299. }
  300. return "отправлено писем - ".$mail_count;
  301. }
  302. /**
  303. * Check media storage for avatars exist
  304. *
  305. */
  306. public function check_media_storage(){
  307. global $object_types;
  308. $sql='';
  309. foreach($object_types as $key=>&$value){
  310. if($key==5 || $key==6) continue;
  311. $sql.="SELECT {$key} as `object_type`,`id` FROM `{$value['class']}` UNION ";
  312. }
  313. unset($value);
  314. $sql=substr($sql,0,-7);
  315. $this->db->query($sql);
  316. $result=&$this->db->get_result();
  317. global $avatar_types;
  318. foreach($result as &$value){
  319. $path=__MEDIA_STORAGE_PATH.'/avatars/objects/'.$value['object_type'].'/'.$value['id'];
  320. if(!file_exists($path)){
  321. umask(0);
  322. if(@mkdir($path)){
  323. foreach($avatar_types as $key2=>&$value2){
  324. $path2=$path.'/'.$key2;
  325. if(!@mkdir($path2)) echo 'Не удалось создать '.$path2.'<br/>';
  326. }unset($value2);
  327. if($value['object_type']==4){
  328. $path2=$path.'/logotips';
  329. if(!@mkdir($path2)) echo 'Не удалось создать '.$path2.'<br/>';
  330. }
  331. }else echo 'Не удалось создать '.$path.' <br/>';
  332. }else {
  333. foreach($avatar_types as $key2=>&$value2){
  334. if(!file_exists($path.'/'.$key2)){
  335. umask(0);
  336. if(!@mkdir($path.'/'.$key2)) echo 'Не удалось создать '.$path.'/'.$key2.'<br/>';
  337. }unset($value2);
  338. }
  339. }
  340. if($value['object_type']==4 && !file_exists($path.'/logotips')){
  341. if(!mkdir($path.'/logotips')) echo 'Не удалось создать '.$path.'/logotips<br/>';
  342. }
  343. }
  344. unset ($value);
  345. $sql='SELECT u.`id` FROM `users` u';
  346. $this->db->query($sql);
  347. $result=&$this->db->get_result();
  348. foreach ($result as &$value) {
  349. $path=__MEDIA_STORAGE_PATH.'/avatars/users/'.$value['id'];
  350. if(!file_exists($path)){
  351. umask(0);
  352. if(@mkdir($path)){
  353. foreach($avatar_types as $key2=>&$value2){
  354. $path2=$path.'/'.$key2;
  355. if(!mkdir($path2)) echo 'Не удалось создать '.$path2.'<br/>';
  356. }unset($value2);
  357. }else echo 'Не удалось создать '.$path.' <br/>';
  358. }else {
  359. foreach($avatar_types as $key2=>&$value2){
  360. if(!file_exists($path.'/'.$key2)){
  361. umask(0);
  362. if(!@mkdir($path.'/'.$key2)) echo 'Не удалось создать '.$path.'/'.$key2.'<br/>';
  363. }unset($value2);
  364. }
  365. }
  366. }unset($value);
  367. $sql='SELECT p.`id`, p.`object_type`, p.`user_id`, p.`object_id` FROM `photoalbums` p';
  368. $this->db->query($sql);
  369. $result=&$this->db->get_result();
  370. global $image_types;
  371. foreach ($result as &$value) {
  372. if($value['user_id']>0)$path=__MEDIA_STORAGE_PATH.'/photos/users/'.$value['user_id'].'/'.$value['id'];
  373. else $path=__MEDIA_STORAGE_PATH.'/photos/objects/'.(($value['object_type']==5)?1:$value['object_type']).'/'.$value['object_id'].'/'.$value['id'];
  374. if(!file_exists($path)){
  375. umask(0);
  376. if(@mkdir($path)){
  377. foreach($image_types as $key2=>&$value2){
  378. if($key2==1)continue;
  379. $path2=$path.'/'.$key2;
  380. if(!@mkdir($path2)) echo 'Не удалось создать '.$path2.'<br/>';
  381. }unset($value2);
  382. }else echo 'Не удалось создать '.$path.' <br/>';
  383. }else {
  384. foreach($image_types as $key2=>&$value2){
  385. if($key2==1)continue;
  386. if(!file_exists($path.'/'.$key2)){
  387. umask(0);
  388. if(!@mkdir($path.'/'.$key2)) echo 'Не удалось создать '.$path.'/'.$key2.'<br/>';
  389. }
  390. }unset($value2);
  391. }
  392. }unset($value);
  393. }
  394. //рассылка юзерам, которые не заходили на сайт за опеределенный интервал времени
  395. public function email_broadcast($interval)
  396. {
  397. $sql="SELECT MAX(cv.`date`) as `maxdate`,MAX(UNIX_TIMESTAMP(cv.`date`)) as `date`,COUNT(DISTINCT e.`id`) as `events_count`,COUNT(DISTINCT m.`id`) as `message_count` ,u.`id` ,u.`login`,u.`email` ,u.`name`, u.`surname` ";
  398. include_once(__ENGINE_PATH.'/functions/classes/class_eventer.php');
  399. $eventer=new Eventer($this->db);
  400. foreach($eventer->event_types as $key=>$value){
  401. $sql.=" ,COUNT(DISTINCT IF(e.`type`={$key},e.`id`,NULL)) as `event_type_{$key}` ";
  402. }
  403. $sql.="FROM `users` u
  404. INNER JOIN `visits` cv ON cv.`user_id`=u.`id`
  405. LEFT JOIN `events` e ON e.`to`=u.`id` AND e.`to_readed`=0 AND e.`created`<NOW()
  406. LEFT JOIN `user_messages` m ON m.`to`=u.`id` AND m.`to_readed`=0
  407. WHERE u.`group`<50
  408. GROUP BY u.`id`
  409. HAVING DATEDIFF(NOW(),MAX( cv.`date`))>0 AND DATEDIFF(NOW(),MAX( cv.`date`))%{$interval}=0 AND (`events_count`>0 OR `message_count`>0)";
  410. if($this->db->query($sql))
  411. {
  412. include_once(__ENGINE_PATH.'/functions/classes/class_mailer.php');
  413. $mailer=new Mailer();
  414. include_once(__ENGINE_PATH.'/functions/classes/class_eventer.php');
  415. $eventer=new Eventer($this->db);
  416. $listeners=&$this->db->get_result();
  417. global $region_codes;
  418. $m_count=0;
  419. foreach($listeners as $adresat)
  420. {
  421. $user_id=$adresat['id'];
  422. $no_text=true;
  423. $subject='';
  424. $msg='';
  425. include(__ENGINE_PATH.'/functions/actions/users.reminder_all.php');
  426. if(count($result['important'])>0 || count($result['participation'])>0 || count($result['remind'])>0 || count($result['interesting'])>0){
  427. $adresat_email = $adresat['email'];
  428. include(__ENGINE_PATH.'/templates/email.broadcast.php');
  429. if(!@$mailer->mail($adresat['email'], $subject,$msg)) {
  430. echo ('Не удалось отправить информацию пользователям, не заходившим длительное время');
  431. }else {
  432. $m_count++;
  433. }
  434. }
  435. }
  436. return "отправлено писем - {$m_count}";
  437. }
  438. return false;
  439. }
  440. //рассыдка админам не заходившим на сайте $missing_days дней
  441. public function email_admins_broadcast($missing_days)
  442. {
  443. include_once(__ENGINE_PATH.'/functions/classes/class_eventer.php');
  444. $eventer=new Eventer($this->db);
  445. $sql="SELECT MAX(cv.`date`) as `maxdate`,MAX(UNIX_TIMESTAMP(cv.`date`)) as `date`,COUNT(DISTINCT e.`id`) as `events_count`,COUNT(DISTINCT m.`id`) as `message_count` ,u.`id` , ur.`region` ,u.`login`,u.`group`,u.`email` ,u.`name`, u.`surname` ";
  446. foreach($eventer->event_types as $key=>$value)
  447. {
  448. $sql.=" ,COUNT(DISTINCT IF(e.`type`={$key},e.`id`,NULL)) as `event_type_{$key}` ";
  449. }
  450. $sql.="FROM `users` u
  451. LEFT JOIN `users_regions` ur ON ur.`user_id`=u.`id`
  452. INNER JOIN `cms_visits` cv ON cv.`user_id`=u.`id`
  453. LEFT JOIN `events` e ON e.`to`=u.`id` AND e.`to_readed`=0 AND e.`created`<NOW()
  454. LEFT JOIN `user_messages` m ON m.`to`=u.`id` AND m.`to_readed`=0
  455. WHERE u.`group`>=90
  456. GROUP BY u.`id` , ur.`region`
  457. HAVING DATEDIFF(NOW(),MAX( cv.`date`))>0 AND DATEDIFF(NOW(),MAX( cv.`date`))%{$missing_days}=0";
  458. if($this->db->query($sql))
  459. {
  460. include_once(__ENGINE_PATH.'/functions/classes/class_mailer.php');
  461. $mailer=new Mailer();
  462. $listeners=&$this->db->get_result();
  463. global $region_codes;
  464. $m_count=0;
  465. include_once(__ENGINE_PATH.'/cms/functions/classes/class_objects.php');
  466. $object_objects=new Objects();
  467. foreach($listeners as $adresat)
  468. {
  469. $objects=&$object_objects->get_objects_count('(o.`moderated`=0 OR (om.`id` is not NULL AND om.`created`<(NOW()-INTERVAL '.__MAX_MODIFICATION_MODERATED_HOURS.' HOUR)) OR (om2.`id` is not NULL AND om2.`created`<(NOW()-INTERVAL '.__MAX_MODIFICATION_MODERATED_HOURS.' HOUR)))',$adresat['region'],$adresat['group']);
  470. $objects_count=$objects[0];
  471. //$censored=&$object_objects->get_objects_count(0,0,'` DESC',array('user_id'),'o.`censored`=1',0,0,$adresat['region'],true);
  472. $censored_count=0;
  473. $user_id=$adresat['id'];
  474. $no_text=true;
  475. include(__ENGINE_PATH.'/functions/actions/users.reminder_all.php');
  476. if( $objects_count > 0 || $censored_count >0 || count($result['important'])>0 || count($result['participation'])>0 || count($result['remind'])>0 || count($result['interesting'])>0)
  477. {
  478. $subject='';
  479. $msg='';
  480. $adresat_email = '';
  481. include(__ENGINE_PATH.'/templates/email.broadcast.php');
  482. if(!@$mailer->mail($adresat['email'], $subject,$msg)) {
  483. trigger_error('Не удалось отправить информацию об админах, не заходивших в CMS длительное время',E_USER_WARNING);
  484. }
  485. else $m_count++;
  486. }
  487. }
  488. return "отправлено писем - {$m_count}";
  489. }
  490. return false;
  491. }
  492. public function check_missing_filial_admins($actual_after_days,$emails)
  493. {
  494. $sql="SELECT MAX(cv.`date`) as `maxdate`,MAX(UNIX_TIMESTAMP(cv.`date`)) as `date`,cv.`user_id` ,u.`login`,u.`group` ,u.`name`, u.`surname`,GROUP_CONCAT(DISTINCT ur.`region`) as `regions`
  495. FROM `users` u
  496. LEFT JOIN `cms_visits` cv ON cv.`user_id`=u.`id`
  497. LEFT JOIN `users_regions` ur ON ur.`user_id`=u.`id`
  498. WHERE u.`group`>=80 AND u.`group`<100 AND u.`id`!=8439 /*татьяна*/
  499. GROUP BY cv.`user_id`
  500. HAVING `maxdate`<(NOW()-INTERVAL {$actual_after_days} DAY)";
  501. include_once(__ENGINE_PATH.'/functions/subfunctions/common.users_groups_arrays.php');
  502. if ($this->db->query($sql))
  503. {
  504. $admins=$this->db->get_result();
  505. //отправляем уведомление
  506. if(count($admins) > 0)
  507. {
  508. include_once(__ENGINE_PATH.'/functions/classes/class_mailer.php');
  509. $mailer=new Mailer();
  510. global $region_codes;
  511. $subject='';
  512. $msg='';
  513. include(__ENGINE_PATH.'/templates/email.missing_admins.php');
  514. if(!@$mailer->mail($emails, $subject,$msg)) {
  515. trigger_error('Не удалось отправить информацию об админах, не заходивших в CMS длительное время',E_USER_WARNING);
  516. }
  517. }
  518. }
  519. }
  520. //формируем таблицу последних посещений
  521. public function visit_last_days(){
  522. //обвновляем данные вспомогательной таблицы для посещений
  523. $sql='UPDATE `visits` SET `guest_id`=`user_id` WHERE `user_id`>0';
  524. $result=$this->db->query($sql);
  525. if(!$result) trigger_error('Не удалось обновить `visits`',E_USER_WARNING);
  526. $sql='TRUNCATE TABLE `visits_last_days`';
  527. if(!$result || !$this->db->query($sql)) {
  528. $result=false;
  529. trigger_error('Не удалось очистить `visits_last_days`',E_USER_WARNING);
  530. }
  531. $last_month=gmdate("Y-m-d",gmmktime(gmdate('H'),gmdate('i'),gmdate('s'),gmdate('m')-1,gmdate('d'),gmdate('Y')));
  532. $sql='INSERT INTO `visits_last_days` (`last_visit`,`object_type`,`object_id`,`user_id`,`guest_id`) SELECT MAX(`date`), `object_type`, `object_id`, `user_id`, `guest_id` FROM `visits` WHERE `date`>=\''.$last_month.'\' GROUP BY `object_type`, `object_id`, `guest_id`';
  533. if(!$result || !$this->db->query($sql)) {
  534. $result=false;
  535. trigger_error('Не удалось сформировать `visits_last_days`',E_USER_WARNING);
  536. }
  537. $sql='UPDATE `visits_last_days` SET `object_type`=1 WHERE `object_type`=5';
  538. if(!$result || !$this->db->query($sql)) {
  539. $result=false;
  540. trigger_error('Не удалось подготовить `visits_last_days` для консультантов',E_USER_WARNING);
  541. }
  542. return $result;
  543. }
  544. public function visits_intermediate_clear()
  545. {
  546. $func_report = array('replace'=>0, 'truncate'=>0);
  547. $this->db->query('SELECT MAX(`id`) as `max_id` FROM `visits_intermediate`');
  548. $id = $this->db->get_result();
  549. if (isset($id[0]['max_id'])) {
  550. $id = $id[0]['max_id'];
  551. if (is_numeric($id) && $id > 0) {
  552. if ($this->db->query('INSERT INTO `visits` SELECT `date`, `object_type`, `object_id`, `ip`, `browser`, `user_id`, `guest_id`, `ip_region` FROM `visits_intermediate` WHERE `id`<='.$id))
  553. $func_report['replace'] = 1;
  554. if ($this->db->query('DELETE FROM `visits_intermediate` WHERE `id`<='.$id))
  555. $func_report['truncate'] = 1;
  556. return 'таблица `visits` '.(!$func_report['replace'] ? 'НЕ ' : 'успешно ').'обновлена, данными из таблицы `visits_intermediate`; таблица `visits_intermediate` '.(!$func_report['truncate'] ? 'НЕ ' : 'успешно ').'очищена';
  557. }
  558. return 'неверно определен ID последней записи ('.$id.')';
  559. }
  560. return 'пустая таблица `visits_intermediate` или ошибка запроса';
  561. }
  562. //сворачиваем таблицы посещений
  563. public function visits_itog($visits_actual_days = 1, $visits_itog_actual_days = 30)
  564. {
  565. $func_report = array('visits_update_guestid_field'=>0, 'visits_visits_itog'=>0, 'visits_delete_old'=>0, 'visits_update_objects'=>0, 'visits_visits_interval_itog'=>0);
  566. //обвновляем данные вспомогательной таблицы для посещений
  567. $result = $this->db->query('UPDATE `visits` SET `guest_id`=`user_id` WHERE `user_id`>0 AND `user_id`!=`guest_id`');
  568. if ($result) {
  569. $func_report['visits_update_guestid_field'] = 1;
  570. //сворачиваем итоговые посещения
  571. $sql = 'REPLACE INTO `visits_itog` (`date`,`object_type`, `object_id`,`visits`, `unique_visits`)
  572. SELECT DATE(`date`) as mydate, `object_type`, `object_id`, COUNT(`guest_id`), COUNT(DISTINCT `guest_id`) FROM `visits`
  573. WHERE `date`>=DATE(NOW() - INTERVAL 1 DAY ) GROUP BY mydate, `object_id`, `object_type`';
  574. $result = $this->db->query($sql);
  575. if ($result) {
  576. $func_report['visits_visits_itog'] = 1;
  577. if ($this->db->query('DELETE FROM `visits` WHERE `date`<(NOW()-INTERVAL '.$visits_actual_days.' DAY)')
  578. && $this->db->query('DELETE FROM `visits_itog` WHERE `date`<(NOW()-INTERVAL '.$visits_itog_actual_days.' DAY)')
  579. && $this->db->query('DELETE FROM `cms_visits` WHERE `date`<(NOW()-INTERVAL '.$visits_itog_actual_days.' DAY)'))
  580. $func_report['visits_delete_old'] = 1;
  581. //обновляем количество посещений в объектах
  582. $update_obj = true;
  583. global $object_types;
  584. foreach ($object_types as $key => $value) {
  585. if (!in_array($key, array(5, 6))) {
  586. if ($key == 1) $object_type_where = 'vi.`object_type` IN(1,5)';
  587. else $object_type_where = 'vi.`object_type`='.$key;
  588. $sql="UPDATE `".$value['class']."` o SET o.`visits`=(SELECT IF(SUM(vi.`visits`) IS NOT NULL,SUM(vi.`visits`),0) FROM `visits_itog` vi WHERE vi.`object_id`=o.`id` AND {$object_type_where}),o.`unique_visits`=(SELECT IF(SUM(vi.`unique_visits`) IS NOT NULL,SUM(vi.`unique_visits`),0) FROM `visits_itog` vi WHERE vi.`object_id`=o.`id` AND {$object_type_where})";
  589. if (!$this->db->query($sql)) $update_obj = false;
  590. }
  591. }
  592. if ($update_obj) $func_report['visits_update_objects'] = 1;
  593. //обновляем кол-во посещений за промежуток времени
  594. $sql = "
  595. REPLACE INTO `visits_interval_itog`(`object_type`, `object_id`, `visits_last1month`, `visits_last3month`, `unique_visits_last1month`, `unique_visits_last3month`)
  596. (SELECT
  597. `object_type`,
  598. `object_id`,
  599. SUM(IF(`date` >= (DATE(NOW())-INTERVAL 1 MONTH), `visits`, 0)) as `visits_last1month`,
  600. SUM(IF(`date` >= (DATE(NOW())-INTERVAL 3 MONTH), `visits`, 0)) as `visits_last3month`,
  601. SUM(IF(`date` >= (DATE(NOW())-INTERVAL 1 MONTH), `unique_visits`, 0)) as `unique_visits_last1month`,
  602. SUM(IF(`date` >= (DATE(NOW())-INTERVAL 3 MONTH), `unique_visits`, 0)) as `unique_visits_last3month`
  603. FROM `visits_itog`
  604. WHERE `object_type` NOT IN (0,6)
  605. GROUP BY `object_type`, `object_id`
  606. )
  607. ";
  608. if ($this->db->query($sql)) $func_report['visits_visits_interval_itog'] = 1;
  609. }
  610. }
  611. return 'поле `guest_id` таблицы `visits` '.(!$func_report['visits_update_guestid_field'] ? 'НЕ ' : 'успешно ').'обновлено; таблица `visits_itog` '.(!$func_report['visits_visits_itog'] ? 'НЕ ' : 'успешно ').'обновлена; таблицы `visits, `cms_visits`, `visits_itog` '.(!$func_report['visits_visits_itog'] ? 'НЕ ' : 'успешно ').'очищены от старых записей; поле `visits` в таблицах объектов '.(!$func_report['visits_visits_itog'] ? 'НЕ ' : 'успешно ').'обновлено; таблица `visits_interval_itog` '.(!$func_report['visits_visits_itog'] ? 'НЕ ' : 'успешно ').'обновлена';
  612. }
  613. //сворачиваем таблицы посещений баннеров
  614. public function banners_visits_itog($visits_actual_days,$update_now=false)
  615. {
  616. $func_report = array('banners_visits_itog'=>0, 'banner_zones_visits_itog'=>0);
  617. //сворачиваем итоговые посещения
  618. $sql='REPLACE INTO `banners_visits_itog` (`date`,`banner_id`,`visits`, `clicks`)
  619. SELECT DATE(`date`) as mydate, `banner_id`, SUM(IF(IF(`event`=1,1,0) is not null,IF(`event`=1,1,0),0)), SUM(IF(IF(`event`=2,1,0) is not null,IF(`event`=2,1,0),0)) FROM `banners_visits`
  620. WHERE DATE(`date`)=DATE(NOW()';
  621. if(!$update_now)$sql.=' - INTERVAL 1 DAY ';
  622. $sql.=') GROUP BY mydate, `banner_id`';
  623. if ($this->db->query($sql))
  624. {
  625. $sql='DELETE FROM `banners_visits` WHERE `date`<(NOW()-INTERVAL '.$visits_actual_days.' DAY)';
  626. $this->db->query($sql);
  627. $func_report['banners_visits_itog'] = 1;
  628. }
  629. $sql='REPLACE INTO `banner_zones_visits_itog` (`date`,`zone_id`,`visits`, `clicks`)
  630. SELECT DATE(`date`) as mydate, `zone_id`, SUM(IF(IF(`event`=1,1,0) is not null,IF(`event`=1,1,0),0)), SUM(IF(IF(`event`=2,1,0) is not null,IF(`event`=2,1,0),0)) FROM `banner_zones_visits`
  631. WHERE DATE(`date`)=DATE(NOW()';
  632. if(!$update_now)$sql.=' - INTERVAL 1 DAY ';
  633. $sql.=') GROUP BY mydate, `zone_id`';
  634. if ($this->db->query($sql))
  635. {
  636. $sql='DELETE FROM `banner_zones_visits` WHERE `date`<(NOW()-INTERVAL 14 DAY)';
  637. $this->db->query($sql);
  638. $func_report['banner_zones_visits_itog'] = 1;
  639. }
  640. return 'таблица `banners_visits_itog` '.(!$func_report['banners_visits_itog'] ? 'НЕ ' : 'успешно ').'обновлена, таблица `banner_zones_visits_itog` '.(!$func_report['banner_zones_visits_itog'] ? 'НЕ ' : 'успешно ').'обновлена';
  641. }
  642. //отключаем прошедшие баннеры
  643. public function banners_deactivate_old(){
  644. $sql='UPDATE `banners` SET `active`=0 WHERE `public_date_end`<now();';
  645. return $this->db->query($sql);
  646. }
  647. //очистка таблицы object_links от мертвых ссылок
  648. public function clear_object_links($object_types)
  649. {
  650. set_time_limit(600);
  651. foreach($object_types as $key=>$value)
  652. {
  653. $sql='
  654. SELECT l.`object1_id` as `dead_id`, COUNT(o.`id`) as `count`
  655. FROM `object_links` l
  656. LEFT JOIN `'.$value['class'].'` o ON l.`object1_id`=o.`id`
  657. WHERE l.`object1_type`='.$key.'
  658. GROUP BY `dead_id`
  659. HAVING `count`=0
  660. UNION
  661. SELECT l.`object2_id` as `dead_id`, COUNT(o.`id`) as `count`
  662. FROM `object_links` l
  663. LEFT JOIN `'.$value['class'].'` o ON l.`object2_id`=o.`id`
  664. WHERE l.`object2_type`='.$key.'
  665. GROUP BY `dead_id`
  666. HAVING `count`=0
  667. ';
  668. if($this->db->query($sql))
  669. {
  670. $result=$this->db->get_result();
  671. if(count($result))
  672. {
  673. $sql='DELETE FROM `object_links` WHERE ';
  674. $i=0;
  675. foreach($result as $key2=>$value2)
  676. {
  677. $sql.='(`object1_type`='.$key.' AND `object1_id`='.$value2['dead_id'].') OR (`object2_type`='.$key.' AND `object2_id`='.$value2['dead_id'].') OR ';
  678. $i++;
  679. if($i==5)
  680. {
  681. $sql=substr($sql,0,-4);
  682. $this->db->query($sql);
  683. $sql='DELETE FROM `object_links` WHERE ';
  684. $i=0;
  685. }
  686. }
  687. if($i>0){
  688. $sql=substr($sql,0,-4);
  689. $this->db->query($sql);
  690. }
  691. }
  692. }
  693. }
  694. }
  695. //свернуть голоса у сообщений
  696. public function vote_message_itog()
  697. {
  698. $sql='UPDATE `messages` m SET
  699. m.`vote_ok`=m.`vote_ok`+(SELECT IF(SUM(m2.`vote_ok`) is not NULL,SUM(m2.`vote_ok`),0) FROM `messages_votes` m2 WHERE m2.`message_id`=m.`id` AND m2.`vote_ok`!=0 AND m2.`date`<(NOW() - INTERVAL 6 MONTH)),
  700. m.`vote_bad`=m.`vote_bad`+(SELECT IF(SUM(m2.`vote_bad`) is not NULL,SUM(m2.`vote_bad`),0) FROM `messages_votes` m2 WHERE m2.`message_id`=m.`id` AND m2.`vote_bad`!=0 AND m2.`date`<(NOW() - INTERVAL 6 MONTH)),
  701. m.`spam`=m.`spam`+(SELECT IF(SUM(m2.`spam`) is not NULL,SUM(m2.`spam`),0) FROM `messages_votes` m2 WHERE m2.`message_id`=m.`id` AND m2.`spam`!=0 AND m2.`date`<(NOW() - INTERVAL 6 MONTH)),
  702. m.`vote_count`=m.`vote_count`+(SELECT COUNT(m2.`message_id`) FROM `messages_votes` m2 WHERE m2.`message_id`=m.`id` AND m2.`spam`=0 AND m2.`date`<(NOW() - INTERVAL 6 MONTH))';
  703. if($this->db->query($sql)) {
  704. $sql='DELETE FROM `messages_votes` WHERE `date`<(NOW() - INTERVAL 6 MONTH)';
  705. return ($this->db->query($sql));
  706. }
  707. }
  708. //свернуть голоса у отзывов
  709. public function vote_review_itog()
  710. {
  711. $sql='UPDATE `reviews` r SET
  712. r.`vote_ok`=r.`vote_ok`+(SELECT IF(SUM(r2.`vote_ok`) is not NULL,SUM(r2.`vote_ok`),0) FROM `reviews_votes` r2 WHERE r2.`review_id`=r.`id` AND r2.`vote_ok`!=0 AND r2.`date`<(NOW() - INTERVAL 6 MONTH)),
  713. r.`vote_bad`=r.`vote_bad`+(SELECT IF(SUM(r2.`vote_bad`) is not NULL,SUM(r2.`vote_bad`),0) FROM `reviews_votes` r2 WHERE r2.`review_id`=r.`id` AND r2.`vote_bad`!=0 AND r2.`date`<(NOW() - INTERVAL 6 MONTH)),
  714. r.`vote_count`=r.`vote_count`+(SELECT COUNT(r2.`review_id`) FROM `reviews_votes` r2 WHERE r2.`review_id`=r.`id` AND r2.`date`<(NOW() - INTERVAL 6 MONTH))';
  715. if($this->db->query($sql)) {
  716. $sql='DELETE FROM `reviews_votes` WHERE `date`<(NOW() - INTERVAL 6 MONTH)';
  717. return ($this->db->query($sql));
  718. }
  719. }
  720. public function remove_media_storage_tempdirs()
  721. {
  722. $media_storages=array(__MEDIA_STORAGE_PATH.'/photos/temp',__MEDIA_STORAGE_PATH.'/avatars/temp',__MEDIA_STORAGE_PATH.'/banners/temp');
  723. foreach ($media_storages as $media_storage){
  724. $handle = opendir($media_storage);
  725. while (false !== ($photoalbum_id = readdir($handle)))
  726. {
  727. if ($photoalbum_id!=".." && $photoalbum_id!="." && is_dir($media_storage.'/'.$photoalbum_id))
  728. {
  729. if((time()-filemtime($media_storage.'/'.$photoalbum_id))>259200)
  730. {
  731. if(!dir_remove($media_storage.'/'.$photoalbum_id)) trigger_error('Невозможно удалить временную папку '.$media_storage.'/'.$photoalbum_id,E_USER_ERROR);
  732. }
  733. }
  734. }
  735. closedir($handle);
  736. }
  737. }
  738. public function clear_old_events()
  739. {
  740. $sql='DELETE FROM `events` WHERE `created`<(NOW()-INTERVAL 6 MONTH)';
  741. return ($this->db->query($sql));
  742. }
  743. //удаляет сообщения пользователей, когда они удалили их с обоих сторон
  744. public function remove_user_messages()
  745. {
  746. $sql='DELETE FROM `user_messages` WHERE `user_remove`=1 AND `to_remove`=1';
  747. return ($this->db->query($sql));
  748. }
  749. public function change_wallpaper()
  750. {
  751. $folder = __APP_PATH.'/design/background';
  752. $img = null;
  753. $fileList = array();
  754. $handle = @opendir($folder);
  755. if(!$handle){
  756. trigger_error('Не удалось открыть папку '.$folder,E_USER_ERROR);
  757. return false;
  758. }
  759. while (false !== ($file = readdir($handle))) {
  760. if(preg_match('|.+\.jpg|isu',$file) && $file != "ny2013.jpg"){
  761. $fileList[] = $file;
  762. }
  763. }
  764. closedir($handle);
  765. $count = count($fileList);
  766. if ($count > 0) {
  767. $imageNumber = rand(0,$count-1);
  768. $img = $fileList[$imageNumber];
  769. }
  770. if(in_array(gmdate("d.m.Y"), array("31.12.2012","01.01.2013","02.01.2013","03.01.2013","04.01.2013","05.01.2013","06.01.2013","14.01.2013"))) $img = "ny2013.jpg";
  771. //запись в файл
  772. $file=__ENGINE_PATH.'/templates/'.App::appPrefix().'/background.tpl';
  773. $fp=@fopen($file,'w');
  774. if($fp){
  775. fwrite($fp,$img);
  776. fclose($fp);
  777. }else trigger_error('Не удалось открыть для записи '.$file,E_USER_ERROR);
  778. }
  779. public function optimize_tables(array $tables)
  780. {
  781. if(count($tables)==0)return;
  782. foreach($tables as $item){
  783. $sql="OPTIMIZE TABLE `{$item}`";
  784. $this->db->query($sql);
  785. }
  786. foreach($tables as $item){
  787. $sql="ALTER TABLE `{$item}`";
  788. $this->db->query($sql);
  789. }
  790. return;
  791. }
  792. //remove dublicats from tables
  793. public function check_tables_dublicats(){
  794. $total_count=0;
  795. $sql='SELECT ol.`object_links_id` FROM `object_links` ol
  796. INNER JOIN `object_links` ol2 ON
  797. ol.`object_links_id`>ol2.`object_links_id` AND
  798. ol.`main_link`=ol2.`main_link` AND
  799. ol.`additional_link`=ol2.`additional_link` AND
  800. (
  801. ol2.`object1_id`=ol.`object2_id` AND
  802. (
  803. ol2.`object1_type`=ol.`object2_type` OR (ol2.`object1_type` IN(1,5) AND ol.`object2_type` IN(1,5))
  804. ) AND
  805. ol2.`object2_id`=ol.`object1_id` AND
  806. (
  807. ol2.`object2_type`=ol.`object1_type` OR (ol2.`object2_type` IN(1,5) AND ol.`object1_type` IN(1,5))
  808. )
  809. )';
  810. $this->db->query($sql);
  811. $result=&$this->db->get_result();
  812. if(count($result)>0){
  813. $sql='DELETE FROM `object_links` WHERE ';
  814. foreach($result as $value) $sql.='`object_links_id`='.$value['object_links_id'].' OR ';
  815. $sql=substr($sql,0,-4);
  816. if($this->db->query($sql)) $total_count+=count($result);
  817. }
  818. $sql='SELECT ol.`object_links_id` FROM `object_links` ol
  819. INNER JOIN `object_links` ol2 ON
  820. ol.`object_links_id`>ol2.`object_links_id` AND
  821. ol.`main_link`=ol2.`main_link` AND
  822. ol.`additional_link`=ol2.`additional_link` AND
  823. (
  824. ol2.`object1_id`=ol.`object1_id` AND
  825. (
  826. ol2.`object1_type`=ol.`object1_type` OR (ol2.`object1_type` IN(1,5) AND ol.`object1_type` IN(1,5))
  827. ) AND
  828. ol2.`object2_id`=ol.`object2_id` AND
  829. (
  830. ol2.`object2_type`=ol.`object2_type` OR (ol2.`object2_type` IN(1,5) AND ol.`object2_type` IN(1,5))
  831. )
  832. )';
  833. $this->db->query($sql);
  834. $result=&$this->db->get_result();
  835. if(count($result)>0){
  836. $sql='DELETE FROM `object_links` WHERE ';
  837. foreach($result as $value) $sql.='`object_links_id`='.$value['object_links_id'].' OR ';
  838. $sql=substr($sql,0,-4);
  839. if($this->db->query($sql)) $total_count+=count($result);
  840. }
  841. if($total_count>0) echo 'Удалено '.$total_count.' дубликатов из `object_links`<br/><br/>'."\n\n";
  842. $total_count=0;
  843. $sql='SELECT ol.`id_object_regions` FROM `object_regions` ol
  844. INNER JOIN `object_regions` ol2 ON
  845. ol.`id_object_regions`>ol2.`id_object_regions` AND
  846. ol.`main_link`=ol2.`main_link` AND
  847. ol.`region`=ol2.`region` AND
  848. (
  849. ol2.`object_id`=ol.`object_id` AND
  850. (
  851. ol2.`object_type`=ol.`object_type` OR (ol2.`object_type` IN(1,5) AND ol.`object_type` IN(1,5))
  852. )
  853. )';
  854. $this->db->query($sql);
  855. $result=&$this->db->get_result();
  856. if(count($result)>0){
  857. $sql='DELETE FROM `object_regions` WHERE ';
  858. foreach($result as $value) $sql.='`id_object_regions`='.$value['id_object_regions'].' OR ';
  859. $sql=substr($sql,0,-4);
  860. if($this->db->query($sql)) $total_count+=count($result);
  861. }
  862. if($total_count>0) echo 'Удалено '.$total_count.' дубликатов из `object_regions`<br/><br/>'."\n\n";
  863. }
  864. /**
  865. * Rebuild levels in guidelines table
  866. *
  867. */
  868. public function rebuild_guideline_levels(){
  869. $updated_guidelines=0;
  870. $sql='SELECT g.`left_index`, g.`right_index`, g.`id` FROM `guidelines` g ORDER BY g.`left_index`';
  871. $this->db->query($sql);
  872. $result=$this->db->get_result();
  873. foreach($result as $key=>&$value){
  874. $sql='SELECT g.`level` FROM `guidelines` g WHERE g.`left_index`<'.$value['left_index'].' AND g.`right_index`>'.$value['right_index'].' LIMIT 0,1';
  875. $this->db->query($sql);
  876. $result2=$this->db->get_result();
  877. if(count($result2)>0) {
  878. $level=$result2[0]['level']+1;
  879. $sql='UPDATE `guidelines` SET `level`='.$level.' WHERE `id`='.$value['id'];
  880. if($this->db->query($sql)) $updated_guidelines++;
  881. else echo 'CAN NOT EXECUTE: '.$sql.'<br/>' ;
  882. }
  883. }unset($value);
  884. echo 'Всего обновлено: '.$updated_guidelines.'';
  885. }
  886. /**
  887. * пересчет рейтингов для объектов у которых есть блок популярные объекты
  888. *
  889. * @param int $interval numder of days to count visits
  890. */
  891. public function calculate_ratings($interval=28){
  892. global $object_types;
  893. foreach($object_types as $key=>$item){
  894. if($key!=3 && $key!=6 && $key!=14){
  895. $preffix='';
  896. if($key==1)$preffix='t_';
  897. elseif($key==5)$preffix='c_';
  898. $sql=" UPDATE `{$item['class']}` o SET
  899. `{$preffix}rating`=(SELECT COALESCE(SUM(vi.`unique_visits`),0)
  900. FROM `visits_itog` vi WHERE vi.`object_type`".($key==1||$key==5?' IN(1,5)':'='.$key)." AND vi.`object_id`=o.`id` AND DATE(vi.`date`)<=DATE(NOW()) AND vi.`date`>(NOW()-INTERVAL $interval DAY))";
  901. $this->db->query($sql) or trigger_error("Не удалось посчитать рейтинг",E_USER_WARNING);
  902. }
  903. }
  904. }
  905. /**
  906. * пересчет рейтингов для объектов у которых есть блок популярные объекты - новая формула (формула Байеса + просмотры)
  907. * http://habrahabr.ru/company/darudar/blog/143188/#comment_4797256 , http://habrahabr.ru/qa/3491/
  908. */
  909. public function calculate_ratings_baies($types){
  910. global $object_types;
  911. foreach($object_types as $key=>$item){
  912. if(!in_array($key, $types) || in_array($key, array(6,14))) continue;
  913. $preffix='';
  914. if($key==1)$preffix='t_';
  915. elseif($key==5)$preffix='c_';
  916. $m = 3;//минимальное кол-во голосов для участия в рейтинге
  917. $c = 2;
  918. $v = "IF(SUM(r.`value_itog`) IS NULL, 0, SUM(r.`value_itog`))";
  919. $r = "(SUM(r.`value_itog`)/COUNT(r.`id`))";
  920. $k = "(1.5/5)";
  921. $formula = "ROUND((IF((({$v}/({$v}+{$m}))*{$r}) IS NULL, 0, (({$v}/({$v}+{$m}))*{$r})) + ({$m}/({$v}+{$m}))*{$c})*{$k},3)";
  922. $sql2 = "ROUND((((o.`{$preffix}srating_itog`*o.`{$preffix}svote_itog`)/(o.`{$preffix}svote_itog`+{$m}))+(({$m}*{$c})/({$m}+o.`{$preffix}svote_itog`)))/5 ,3)";
  923. if($key == 2){
  924. $k = "(1/5)";
  925. $sql2 = "
  926. SELECT {$formula}
  927. FROM `object_links` ol
  928. JOIN `reviews` r ON r.`object_type`=3 AND r.`object_id`=ol.`object1_id`
  929. WHERE ol.`object2_type`=2 AND ol.`object2_id`=o.`id` AND ol.`object1_type`=3
  930. GROUP BY ol.`object2_id`
  931. UNION SELECT {$c}*{$k}
  932. LIMIT 1
  933. ";
  934. }
  935. elseif($key == 4){
  936. $sql2 .= " +
  937. (SELECT {$formula}
  938. FROM `reviews_objects` ro
  939. JOIN `reviews` r ON r.`id`=ro.`review_id`
  940. WHERE ro.`object_type`=4 AND ro.`object_id`=o.`id`
  941. UNION SELECT {$c}*{$k}
  942. LIMIT 1)
  943. ";
  944. }
  945. elseif($key==5){
  946. $sql2 .= " +
  947. (SELECT {$formula}
  948. FROM `reviews` r
  949. WHERE r.`object_type`=5 AND r.`object_id`=o.`id`
  950. UNION SELECT {$c}*{$k}
  951. LIMIT 1)
  952. ";
  953. }
  954. elseif($key==1){
  955. $sql2 .= " +
  956. (SELECT {$formula}
  957. FROM `reviews_objects` ro
  958. JOIN `reviews` r ON r.`id`=ro.`review_id`
  959. WHERE ro.`object_type`=1 AND ro.`object_id`=o.`id`
  960. UNION SELECT {$c}*{$k}
  961. LIMIT 1)
  962. ";
  963. }
  964. elseif($key==3){
  965. $sql2 .= " +
  966. (SELECT {$formula}
  967. FROM `reviews_objects` ro
  968. JOIN `reviews` r ON r.`id`=ro.`review_id`
  969. WHERE ro.`object_type`=3 AND ro.`object_id`=o.`id`
  970. UNION SELECT {$c}*{$k}
  971. LIMIT 1)
  972. ";
  973. }
  974. elseif($key==12){
  975. $sql2 = "SELECT vii.`visits_last3month` FROM `visits_interval_itog` vii WHERE vii.`object_type`=12 AND vii.`object_id`=o.`id` UNION SELECT 0 LIMIT 1";
  976. }
  977. $sql="UPDATE `{$item['class']}` o SET `{$preffix}rating`=({$sql2})";
  978. $this->db->query($sql) or trigger_error("Не удалось посчитать рейтинг",E_USER_WARNING);
  979. }
  980. }
  981. /**
  982. * Подсчет кол-ва оценок пользователя за мероприятие
  983. * @param $types
  984. */
  985. public function calculate_object_action_rating($types){
  986. global $object_types;
  987. foreach($types as $type){
  988. if(!isset($object_types[$type]) || !in_array($type, array(1,2,4))) continue;
  989. $tbl = $object_types[$type]['class'];
  990. if($type == 4){
  991. $sql = "
  992. SELECT tbl.`id` as `id`, IF(SUM(tbl.`rate`)/SUM(IF(tbl.`count`=0,0,1)) IS NULL, 0, SUM(tbl.`rate`)/SUM(IF(tbl.`count`=0,0,1))) as `rate`, SUM(tbl.`count`) as `count`
  993. FROM
  994. (
  995. SELECT
  996. ol.`object2_id` as `id`, a.`srating_itog` as `rate`, a.`svote_itog` as `count`
  997. FROM
  998. `object_links` ol
  999. JOIN `timetable` t ON t.`id`=ol.`object1_id` AND t.`moderated` = 1 AND t.`block` = 0
  1000. JOIN `actions` a ON t.`action_id`=a.`id`
  1001. WHERE
  1002. ol.`object2_type`=4 AND ol.`object1_type`=6 AND ol.`main_link`=1
  1003. GROUP BY
  1004. ol.`object2_id`, a.`id`
  1005. ) as `tbl`
  1006. GROUP BY tbl.`id`
  1007. ";
  1008. }
  1009. elseif($type==1){
  1010. $sql = "
  1011. SELECT tbl.`id` as `id`, IF(SUM(tbl.`rate`)/SUM(IF(tbl.`count`=0,0,1)) IS NULL, 0, SUM(tbl.`rate`)/SUM(IF(tbl.`count`=0,0,1))) as `rate`, SUM(tbl.`count`) as `count`
  1012. FROM
  1013. (
  1014. SELECT
  1015. ol.`object2_id` as `id`, a.`srating_itog` as `rate`, a.`svote_itog` as `count`
  1016. FROM
  1017. `object_links` ol
  1018. JOIN `timetable` t ON t.`id`=ol.`object1_id` AND t.`moderated` = 1 AND t.`block` = 0
  1019. JOIN `actions` a ON t.`action_id`=a.`id`
  1020. WHERE
  1021. ol.`object2_type`=1 AND ol.`object1_type`=6
  1022. GROUP BY
  1023. ol.`object2_id`, a.`id`
  1024. ) as `tbl`
  1025. GROUP BY tbl.`id`
  1026. ";
  1027. }
  1028. if($type == 2){
  1029. $sql2 = "
  1030. SELECT IF(SUM(a.`srating_itog`)/SUM(IF(a.`svote_itog`=0,0,1)) IS NULL, 0, SUM(a.`srating_itog`)/SUM(IF(a.`svote_itog`=0,0,1)))
  1031. FROM `object_links` ol
  1032. JOIN `actions` a ON a.`id`=ol.`object1_id`
  1033. WHERE ol.`object2_type`=2 AND ol.`object2_id`=o.`id` AND ol.`object1_type`=3
  1034. GROUP BY ol.`object2_id`
  1035. UNION SELECT 0
  1036. LIMIT 1
  1037. ";
  1038. $sql3 = "
  1039. SELECT
  1040. IF(SUM(a.`svote_itog`) IS NULL, 0, SUM(a.`svote_itog`))
  1041. FROM `object_links` ol
  1042. JOIN `actions` a ON a.`id`=ol.`object1_id`
  1043. WHERE ol.`object2_type`=2 AND ol.`object2_id`=o.`id` AND ol.`object1_type`=3
  1044. GROUP BY ol.`object2_id`
  1045. ";
  1046. $sql = "UPDATE `{$tbl}` o SET `srating_itog_action`=({$sql2}), `svote_itog_action`=({$sql3})";
  1047. $this->db->query($sql) or trigger_error("Не удалось посчитать рейтинг",E_USER_WARNING);
  1048. }
  1049. else{
  1050. $sql = "
  1051. DROP TEMPORARY TABLE IF EXISTS `temp_ratings`;
  1052. CREATE TEMPORARY TABLE `temp_ratings`
  1053. {$sql};
  1054. ALTER TABLE `temp_ratings` ADD INDEX `id` (`id`);
  1055. UPDATE `{$tbl}`, `temp_ratings` SET `{$tbl}`.`srating_itog_action` = `temp_ratings`.`rate`, `{$tbl}`.`svote_itog_action` = `temp_ratings`.`count` WHERE `{$tbl}`.`id` = `temp_ratings`.`id`;
  1056. DROP TEMPORARY