PageRenderTime 300ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/controller/cron.php

https://github.com/alugo/Goteo
PHP | 918 lines | 603 code | 132 blank | 183 comment | 118 complexity | fc2816e349ba9112ddda01bddc125f5f MD5 | raw file
Possible License(s): AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /*
  3. * Copyright (C) 2012 Platoniq y Fundación Fuentes Abiertas (see README for details)
  4. * This file is part of Goteo.
  5. *
  6. * Goteo is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Goteo is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Affero General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Affero General Public License
  17. * along with Goteo. If not, see <http://www.gnu.org/licenses/agpl.txt>.
  18. *
  19. */
  20. namespace Goteo\Controller {
  21. use Goteo\Model,
  22. Goteo\Library\Text,
  23. Goteo\Library\Feed,
  24. Goteo\Library\Template,
  25. Goteo\Library\Mail,
  26. Goteo\Library\Paypal,
  27. Goteo\Library\Tpv;
  28. class Cron extends \Goteo\Core\Controller {
  29. public function index () {
  30. die('bad request');
  31. }
  32. /*
  33. * Proceso que ejecuta los cargos, cambia estados, lanza eventos de cambio de ronda
  34. */
  35. public function execute () {
  36. if (!\defined('CRON_EXEC')) {
  37. @mail(\GOTEO_FAIL_MAIL, 'Se ha lanzado MANUALMENTE el cron '. __FUNCTION__ .' en ' . SITE_URL,
  38. 'Se ha lanzado manualmente el cron '. __FUNCTION__ .' en ' . SITE_URL.' a las ' . date ('H:i:s') . ' Usuario '. $_SESSION['user']->id);
  39. echo 'Lanzamiento manual a las ' . date ('H:i:s') . ' <br />';
  40. } else {
  41. echo 'Lanzamiento automatico a las ' . date ('H:i:s') . ' <br />';
  42. }
  43. // a ver si existe el bloqueo
  44. $block_file = GOTEO_PATH.'logs/cron-'.__FUNCTION__.'.block';
  45. if (file_exists($block_file)) {
  46. echo 'Ya existe un archivo de log '.date('Ymd').'_'.__FUNCTION__.'.log<br />';
  47. $block_content = \file_get_contents($block_file);
  48. echo 'El contenido del bloqueo es: '.$block_content;
  49. // lo escribimos en el log
  50. $log_file = GOTEO_PATH.'logs/cron/'.date('Ymd').'_'.__FUNCTION__.'.log';
  51. \file_put_contents($log_file, \ob_get_contents(), FILE_APPEND);
  52. \chmod($log_file, 0777);
  53. /*
  54. @mail(\GOTEO_FAIL_MAIL, 'Cron '. __FUNCTION__ .' bloqueado en ' . SITE_URL,
  55. 'Se ha encontrado con que el cron '. __FUNCTION__ .' está bloqueado el '.date('d-m-Y').' a las ' . date ('H:i:s') . '
  56. El contenido del bloqueo es: '. $block_content);
  57. */
  58. die;
  59. } else {
  60. $block = 'Bloqueo del '.$block_file.' activado el '.date('d-m-Y').' a las '.date ('H:i:s').'<br />';
  61. if (\file_put_contents($block_file, $block, FILE_APPEND)) {
  62. \chmod($block_file, 0777);
  63. echo $block;
  64. } else {
  65. echo 'No se ha podido crear el archivo de bloqueo<br />';
  66. @mail(\GOTEO_FAIL_MAIL, 'Cron '. __FUNCTION__ .' no se ha podido bloquear en ' . SITE_URL,
  67. 'No se ha podido crear el archivo '.$block_file.' el '.date('d-m-Y').' a las ' . date ('H:i:s'));
  68. }
  69. }
  70. echo '<hr />';
  71. // debug para supervisar en las fechas clave
  72. // $debug = ($_GET['debug'] == 'debug') ? true : false;
  73. $debug = true;
  74. // revision de proyectos: dias, conseguido y cambios de estado
  75. // proyectos en campaña,
  76. // (publicados hace más de 40 días que no tengan fecha de pase)
  77. // o (publicados hace mas de 80 días que no tengan fecha de exito)
  78. $projects = Model\Project::getActive();
  79. if ($debug) echo 'Comenzamos con los proyectos en campaña (esto está en '.\LANG.')<br /><br />';
  80. foreach ($projects as $project) {
  81. if ($debug) echo 'Proyecto '.$project->name.'<br />';
  82. // a ver si tiene cuenta paypal
  83. $projectAccount = Model\Project\Account::get($project->id);
  84. if (empty($projectAccount->paypal)) {
  85. if ($debug) echo 'No tiene cuenta PayPal<br />';
  86. // Evento Feed solamente si automático
  87. if (\defined('CRON_EXEC')) {
  88. $log = new Feed();
  89. $log->setTarget($project->id);
  90. $log->populate('proyecto sin cuenta paypal (cron)', '/admin/projects',
  91. \vsprintf('El proyecto %s aun no ha puesto su %s !!!', array(
  92. Feed::item('project', $project->name, $project->id),
  93. Feed::item('relevant', 'cuenta PayPal')
  94. )));
  95. $log->doAdmin('project');
  96. unset($log);
  97. // mail de aviso
  98. $mailHandler = new Mail();
  99. $mailHandler->to = \GOTEO_CONTACT_MAIL;
  100. $mailHandler->toName = 'Goteo.org';
  101. $mailHandler->subject = 'El proyecto '.$project->name.' no tiene cuenta PayPal';
  102. $mailHandler->content = 'Hola Goteo, el proyecto '.$project->name.' no tiene cuenta PayPal y el proceso automatico no podrá tratar los preaprovals al final de ronda.';
  103. $mailHandler->html = false;
  104. $mailHandler->template = null;
  105. $mailHandler->send();
  106. unset($mailHandler);
  107. $task = new Model\Task();
  108. $task->node = \GOTEO_NODE;
  109. $task->text = "Poner la cuenta PayPal al proyecto <strong>{$project->name}</strong> urgentemente!";
  110. $task->url = "/admin/projects/accounts/{$project->id}";
  111. $task->done = null;
  112. $task->saveUnique();
  113. }
  114. }
  115. $log_text = null;
  116. if ($debug) echo 'Minimo: '.$project->mincost.' &euro; <br />';
  117. $execute = false;
  118. $cancelAll = false;
  119. if ($debug) echo 'Obtenido: '.$project->amount.' &euro;<br />';
  120. // porcentaje alcanzado
  121. if ($project->mincost > 0) {
  122. $per_amount = \floor(($project->amount / $project->mincost) * 100);
  123. } else {
  124. $per_amount = 0;
  125. }
  126. if ($debug) echo 'Ha alcanzado el '.$per_amount.' &#37; del minimo<br />';
  127. // los dias que lleva el proyecto (ojo que los financiados llevaran mas de 80 dias)
  128. $days = $project->daysActive();
  129. if ($debug) echo 'Lleva '.$days.' dias desde la publicacion<br />';
  130. /* Verificar si enviamos aviso */
  131. $rest = $project->days;
  132. $round = $project->round;
  133. if ($debug) echo 'Quedan '.$rest.' dias para el final de la '.$round.'a ronda<br />';
  134. // a los 5, 3, 2, y 1 dia para finalizar ronda
  135. if ($round > 0 && in_array((int) $rest, array(5, 3, 2, 1))) {
  136. if ($debug) echo 'Feed publico cuando quedan 5, 3, 2, 1 dias<br />';
  137. // Evento Feed solo si ejecucion automática
  138. if (\defined('CRON_EXEC')) {
  139. $log = new Feed();
  140. $log->setTarget($project->id);
  141. $log->populate('proyecto próximo a finalizar ronda (cron)', '/admin/projects',
  142. Text::html('feed-project_runout',
  143. Feed::item('project', $project->name, $project->id),
  144. $rest,
  145. $round
  146. ));
  147. $log->doAdmin('project');
  148. // evento público
  149. $log->title = $project->name;
  150. $log->url = null;
  151. $log->doPublic('projects');
  152. unset($log);
  153. }
  154. }
  155. // (financiado a los 80 o cancelado si a los 40 no llega al minimo)
  156. // si ha llegado a los 40 dias: mínimo-> ejecutar ; no minimo proyecto y todos los preapprovals cancelados
  157. if ($days >= 40) {
  158. // si no ha alcanzado el mínimo, pasa a estado caducado
  159. if ($project->amount < $project->mincost) {
  160. if ($debug) echo 'Ha llegado a los 40 dias de campaña sin conseguir el minimo, no pasa a segunda ronda<br />';
  161. echo $project->name . ': ha recaudado ' . $project->amount . ', '.$per_amount.'% de ' . $project->mincost . '/' . $project->maxcost . '<br />';
  162. echo 'No ha conseguido el minimo, cancelamos todos los aportes y lo caducamos:';
  163. $cancelAll = true;
  164. $errors = array();
  165. if ($project->fail($errors)) {
  166. $log_text = 'El proyecto %s ha %s obteniendo %s';
  167. } else {
  168. @mail(\GOTEO_FAIL_MAIL,
  169. 'Fallo al archivar ' . SITE_URL,
  170. 'Fallo al marcar el proyecto '.$project->name.' como archivado ' . implode(',', $errors));
  171. echo 'ERROR::' . implode(',', $errors);
  172. $log_text = 'El proyecto %s ha fallado al, %s obteniendo %s';
  173. }
  174. echo '<br />';
  175. // Evento Feed solo si ejecucion automatica
  176. if (\defined('CRON_EXEC')) {
  177. $log = new Feed();
  178. $log->setTarget($project->id);
  179. $log->populate('proyecto archivado (cron)', '/admin/projects',
  180. \vsprintf($log_text, array(
  181. Feed::item('project', $project->name, $project->id),
  182. Feed::item('relevant', 'caducado sin éxito'),
  183. Feed::item('money', $project->amount.' &euro; ('.$per_amount.'&#37;) de aportes sobre minimo')
  184. )));
  185. $log->doAdmin('project');
  186. // evento público
  187. $log->populate($project->name, null,
  188. Text::html('feed-project_fail',
  189. Feed::item('project', $project->name, $project->id),
  190. $project->amount,
  191. $per_amount
  192. ));
  193. $log->doPublic('projects');
  194. unset($log);
  195. //Email de proyecto fallido al autor
  196. Cron\Send::toOwner('fail', $project);
  197. //Email de proyecto fallido a los inversores
  198. Cron\Send::toInvestors('fail', $project);
  199. }
  200. echo '<br />';
  201. } else {
  202. // tiene hasta 80 días para conseguir el óptimo (o más)
  203. if ($days >= 80) {
  204. if ($debug) echo 'Ha llegado a los 80 dias de campaña (final de segunda ronda)<br />';
  205. echo $project->name . ': ha recaudado ' . $project->amount . ', '.$per_amount.'% de ' . $project->mincost . '/' . $project->maxcost . '<br />';
  206. echo 'Ha llegado a los 80 días: financiado. ';
  207. $execute = true; // ejecutar los cargos de la segunda ronda
  208. $errors = array();
  209. if ($project->succeed($errors)) {
  210. $log_text = 'El proyecto %s ha sido %s obteniendo %s';
  211. } else {
  212. @mail(\GOTEO_FAIL_MAIL,
  213. 'Fallo al marcar financiado ' . SITE_URL,
  214. 'Fallo al marcar el proyecto '.$project->name.' como financiado ' . implode(',', $errors));
  215. echo 'ERROR::' . implode(',', $errors);
  216. $log_text = 'El proyecto %s ha fallado al ser, %s obteniendo %s';
  217. }
  218. // Evento Feed y mails solo si ejecucion automatica
  219. if (\defined('CRON_EXEC')) {
  220. $log = new Feed();
  221. $log->setTarget($project->id);
  222. $log->populate('proyecto supera segunda ronda (cron)', '/admin/projects',
  223. \vsprintf($log_text, array(
  224. Feed::item('project', $project->name, $project->id),
  225. Feed::item('relevant', 'financiado'),
  226. Feed::item('money', $project->amount.' &euro; ('.\round($per_amount).'%) de aportes sobre minimo')
  227. )));
  228. $log->doAdmin('project');
  229. // evento público
  230. $log->populate($project->name, null, Text::html('feed-project_finish',
  231. Feed::item('project', $project->name, $project->id),
  232. $project->amount,
  233. \round($per_amount)
  234. ));
  235. $log->doPublic('projects');
  236. unset($log);
  237. //Email de proyecto final segunda ronda al autor
  238. Cron\Send::toOwner('r2_pass', $project);
  239. //Email de proyecto final segunda ronda a los inversores
  240. Cron\Send::toInvestors('r2_pass', $project);
  241. // Tareas para gestionar
  242. // calculamos fecha de passed+90 días
  243. $passtime = strtotime($project->passed);
  244. $limsec = date('d/m/Y', \mktime(0, 0, 0, date('m', $passtime), date('d', $passtime)+89, date('Y', $passtime)));
  245. /*
  246. * Ya no hacemos pagos secundarios mediante sistema
  247. $task = new Model\Task();
  248. $task->node = \GOTEO_NODE;
  249. $task->text = "Hacer los pagos secundarios al proyecto <strong>{$project->name}</strong> antes del día <strong>{$limsec}</strong>";
  250. $task->url = "/admin/accounts/?projects={$project->id}";
  251. $task->done = null;
  252. $task->save();
  253. */
  254. // y preparar contrato
  255. $task = new Model\Task();
  256. $task->node = \GOTEO_NODE;
  257. $task->text = date('d/m/Y').": Enviar datos contrato <strong>{$project->name}</strong>, {$project->user->name}";
  258. //@TODO enlace a gestión de contrato
  259. $task->url = "/admin/projects?proj_name={$project->name}";
  260. $task->done = null;
  261. $task->saveUnique();
  262. // + mail a mercè
  263. @mail(\GOTEO_CONTACT_MAIL,
  264. 'Preparar contrato ' . $project->name,
  265. 'El proyecto '.$project->name.' ha pasado la primera ronda, enviarle los datos de contrato. Se ha creado una tarea para esto.');
  266. }
  267. echo '<br />';
  268. } elseif (empty($project->passed)) {
  269. if ($debug) echo 'Ha llegado a los 40 dias de campaña, pasa a segunda ronda<br />';
  270. echo $project->name . ': ha recaudado ' . $project->amount . ', '.$per_amount.'% de ' . $project->mincost . '/' . $project->maxcost . '<br />';
  271. echo 'El proyecto supera la primera ronda: marcamos fecha';
  272. $execute = true; // ejecutar los cargos de la primera ronda
  273. $errors = array();
  274. if ($project->passed($errors)) {
  275. // se crea el registro de contrato
  276. if (Model\Contract::create($project->id, $errors)) {
  277. echo ' -> Ok:: se ha creado el registro de contrato';
  278. } else {
  279. @mail(\GOTEO_FAIL_MAIL,
  280. 'Fallo al crear registro de contrato ' . SITE_URL,
  281. 'Fallo al crear registro de contrato para el proyecto '.$project->name.': ' . implode(',', $errors));
  282. echo ' -> semi-Ok: se ha actualiuzado el estado del proyecto pero ha fallado al crear el registro de contrato. ERROR: ' . implode(',', $errors);
  283. }
  284. } else {
  285. @mail(\GOTEO_FAIL_MAIL,
  286. 'Fallo al marcar fecha de paso a segunda ronda ' . SITE_URL,
  287. 'Fallo al marcar la fecha de paso a segunda ronda para el proyecto '.$project->name.': ' . implode(',', $errors));
  288. echo ' -> ERROR::' . implode(',', $errors);
  289. }
  290. echo '<br />';
  291. // Evento Feed solo si ejecucion automatica
  292. if (\defined('CRON_EXEC')) {
  293. $log = new Feed();
  294. $log->setTarget($project->id);
  295. $log->populate('proyecto supera primera ronda (cron)', '/admin/projects', \vsprintf('El proyecto %s %s en segunda ronda obteniendo %s', array(
  296. Feed::item('project', $project->name, $project->id),
  297. Feed::item('relevant', 'continua en campaña'),
  298. Feed::item('money', $project->amount.' &euro; ('.\number_format($per_amount, 2).'%) de aportes sobre minimo')
  299. )));
  300. $log->doAdmin('project');
  301. // evento público
  302. $log->populate($project->name, null,
  303. Text::html('feed-project_goon',
  304. Feed::item('project', $project->name, $project->id),
  305. $project->amount,
  306. \round($per_amount)
  307. ));
  308. $log->doPublic('projects');
  309. unset($log);
  310. if ($debug) echo 'Email al autor y a los cofinanciadores<br />';
  311. // Email de proyecto pasa a segunda ronda al autor
  312. Cron\Send::toOwner('r1_pass', $project);
  313. //Email de proyecto pasa a segunda ronda a los inversores
  314. Cron\Send::toInvestors('r1_pass', $project);
  315. // Tarea para hacer los pagos
  316. $task = new Model\Task();
  317. $task->node = \GOTEO_NODE;
  318. $task->text = date('d/m/Y').": Pagar a <strong>{$project->name}</strong>, {$project->user->name}";
  319. $task->url = "/admin/projects/report/{$project->id}";
  320. $task->done = null;
  321. $task->saveUnique();
  322. // + mail a susana
  323. @mail('susana@goteo.org',
  324. 'Pagar al proyecto ' . $project->name,
  325. 'El proyecto '.$project->name.' ha terminado la segunda ronda, hacer los pagos. Se ha creado una tarea para esto.');
  326. }
  327. } else {
  328. if ($debug) echo 'Lleva más de 40 dias de campaña, debe estar en segunda ronda con fecha marcada<br />';
  329. if ($debug) echo $project->name . ': lleva recaudado ' . $project->amount . ', '.$per_amount.'% de ' . $project->mincost . '/' . $project->maxcost . ' y paso a segunda ronda el '.$project->passed.'<br />';
  330. }
  331. }
  332. }
  333. // si hay que ejecutar o cancelar
  334. if ($cancelAll || $execute) {
  335. if ($debug) echo '::::::Comienza tratamiento de aportes:::::::<br />';
  336. if ($debug) echo 'Execute=' . (string) $execute . ' CancelAll=' . (string) $cancelAll . '<br />';
  337. // tratamiento de aportes penddientes
  338. $query = \Goteo\Core\Model::query("
  339. SELECT *
  340. FROM invest
  341. WHERE invest.project = ?
  342. AND (invest.status = 0
  343. OR (invest.method = 'tpv'
  344. AND invest.status = 1
  345. )
  346. OR (invest.method = 'cash'
  347. AND invest.status = 1
  348. )
  349. )
  350. AND (invest.campaign IS NULL OR invest.campaign = 0)
  351. ", array($project->id));
  352. $project->invests = $query->fetchAll(\PDO::FETCH_CLASS, '\Goteo\Model\Invest');
  353. foreach ($project->invests as $key=>$invest) {
  354. $errors = array();
  355. $log_text = null;
  356. $userData = Model\User::getMini($invest->user);
  357. if ($invest->invested == date('Y-m-d')) {
  358. if ($debug) echo 'Aporte ' . $invest->id . ' es de hoy.<br />';
  359. } elseif ($invest->method != 'cash' && empty($invest->preapproval)) {
  360. //si no tiene preaproval, cancelar
  361. echo 'Aporte ' . $invest->id . ' cancelado por no tener preapproval.<br />';
  362. $invest->cancel();
  363. Model\Invest::setDetail($invest->id, 'no-preapproval', 'Aporte cancelado porque no tiene preapproval. Proceso cron/execute');
  364. continue;
  365. }
  366. if ($cancelAll) {
  367. if ($debug) echo 'Cancelar todo<br />';
  368. switch ($invest->method) {
  369. case 'paypal':
  370. $err = array();
  371. if (Paypal::cancelPreapproval($invest, $err, true)) {
  372. $log_text = "Se ha cancelado aporte y preapproval de %s de %s mediante PayPal (id: %s) al proyecto %s del dia %s";
  373. } else {
  374. $txt_errors = implode('; ', $err);
  375. $log_text = "Ha fallado al cancelar el aporte de %s de %s mediante PayPal (id: %s) al proyecto %s del dia %s. <br />Se han dado los siguientes errores: $txt_errors";
  376. }
  377. break;
  378. case 'tpv':
  379. // se habre la operación en optra ventana
  380. $err = array();
  381. if (Tpv::cancelPreapproval($invest, $err, true)) {
  382. $log_text = "Se ha anulado el cargo tpv de %s de %s mediante TPV (id: %s) al proyecto %s del dia %s";
  383. } else {
  384. $txt_errors = implode('; ', $err);
  385. $log_text = "Ha fallado al anular el cargo tpv de %s de %s mediante TPV (id: %s) al proyecto %s del dia %s. <br />Se han dado los siguientes errores: $txt_errors";
  386. }
  387. break;
  388. case 'cash':
  389. if ($invest->cancel(true)) {
  390. $log_text = "Se ha cancelado aporte manual de %s de %s (id: %s) al proyecto %s del dia %s";
  391. } else{
  392. $log_text = "Ha fallado al cancelar el aporte manual de %s de %s (id: %s) al proyecto %s del dia %s. ";
  393. }
  394. break;
  395. }
  396. // Evento Feed admin
  397. $log = new Feed();
  398. $log->setTarget($project->id);
  399. $log->populate('Preapproval cancelado por proyecto archivado (cron)', '/admin/invests', \vsprintf($log_text, array(
  400. Feed::item('user', $userData->name, $userData->id),
  401. Feed::item('money', $invest->amount.' &euro;'),
  402. Feed::item('system', $invest->id),
  403. Feed::item('project', $project->name, $project->id),
  404. Feed::item('system', date('d/m/Y', strtotime($invest->invested)))
  405. )));
  406. $log->doAdmin();
  407. unset($log);
  408. echo 'Aporte '.$invest->id.' cancelado por proyecto caducado.<br />';
  409. $invest->setStatus('4');
  410. Model\Invest::setDetail($invest->id, 'project-expired', 'Aporte marcado como caducado porque el proyecto no ha tenido exito. Proceso cron/execute');
  411. continue;
  412. }
  413. // si hay que ejecutar
  414. if ($execute && empty($invest->payment)) {
  415. if ($debug) echo 'Ejecutando aporte '.$invest->id.' ['.$invest->method.']';
  416. switch ($invest->method) {
  417. case 'paypal':
  418. if (empty($projectAccount->paypal)) {
  419. if ($debug) echo '<br />El proyecto '.$project->name.' no tiene cuenta paypal.<br />';
  420. Model\Invest::setDetail($invest->id, 'no-paypal-account', 'El proyecto no tiene cuenta paypal en el momento de ejecutar el preapproval. Proceso cron/execute');
  421. break;
  422. }
  423. $invest->account = $projectAccount->paypal;
  424. $err = array();
  425. if (Paypal::pay($invest, $err)) {
  426. $log_text = "Se ha ejecutado el cargo a %s por su aporte de %s mediante PayPal (id: %s) al proyecto %s del dia %s";
  427. if ($debug) echo ' -> Ok';
  428. Model\Invest::setDetail($invest->id, 'executed', 'Se ha ejecutado el preapproval, ha iniciado el pago encadenado. Proceso cron/execute');
  429. // si era incidencia la desmarcamos
  430. if ($invest->issue) {
  431. Model\Invest::unsetIssue($invest->id);
  432. Model\Invest::setDetail($invest->id, 'issue-solved', 'La incidencia se ha dado por resuelta al ejecutarse correctamente en el proceso automático');
  433. }
  434. } else {
  435. $txt_errors = implode('; ', $err);
  436. echo 'Aporte ' . $invest->id . ': Fallo al ejecutar cargo paypal: ' . $txt_errors . '<br />';
  437. @mail(\GOTEO_FAIL_MAIL,
  438. 'Fallo al ejecutar cargo Paypal ' . SITE_URL,
  439. 'Aporte ' . $invest->id . ': Fallo al ejecutar cargo paypal: ' . $txt_errors);
  440. if ($debug) echo ' -> ERROR!!';
  441. Model\Invest::setDetail($invest->id, 'execution-failed', 'Fallo al ejecutar el preapproval, no ha iniciado el pago encadenado: ' . $txt_errors . '. Proceso cron/execute');
  442. // Notifiacion de incidencia al usuario
  443. // Obtenemos la plantilla para asunto y contenido
  444. $template = Template::get(37);
  445. // Sustituimos los datos
  446. $subject = str_replace('%PROJECTNAME%', $project->name, $template->title);
  447. $search = array('%USERNAME%', '%PROJECTNAME%', '%PROJECTURL%', '%AMOUNT%', '%DETAILS%');
  448. $replace = array($userData->name, $project->name, SITE_URL . '/project/' . $project->id, $invest->amount, '');
  449. $content = \str_replace($search, $replace, $template->text);
  450. // iniciamos mail
  451. $mailHandler = new Mail();
  452. $mailHandler->from = GOTEO_CONTACT_MAIL;
  453. $mailHandler->to = $userData->email;
  454. $mailHandler->toName = $userData->name;
  455. $mailHandler->subject = $subject;
  456. $mailHandler->content = $content;
  457. $mailHandler->html = true;
  458. $mailHandler->template = $template->id;
  459. if ($mailHandler->send()) {
  460. Model\Invest::setDetail($invest->id, 'issue-notified', "Se ha notificado la incidencia al usuario");
  461. } else {
  462. Model\Invest::setDetail($invest->id, 'issue-notify-failed', "Ha fallado al enviar el mail de notificacion de la incidencia al usuario");
  463. @mail(\GOTEO_FAIL_MAIL,
  464. 'Fallo al enviar email de notificacion de incidencia PayPal' . SITE_URL,
  465. 'Fallo al enviar email de notificacion de incidencia PayPal: <pre>' . print_r($mailHandler, 1). '</pre>');
  466. }
  467. }
  468. break;
  469. case 'tpv':
  470. // los cargos con este tpv vienen ejecutados de base
  471. if ($debug) echo ' -> Ok';
  472. /*
  473. $err = array();
  474. if (Tpv::pay($invest, $err)) {
  475. echo 'Cargo sermepa correcto';
  476. $log_text = "Se ha ejecutado el cargo a %s por su aporte de %s mediante TPV (id: %s) al proyecto %s del dia %s";
  477. } else {
  478. $txt_errors = implode('; ', $err);
  479. echo 'Fallo al ejecutar cargo sermepa: ' . $txt_errors;
  480. $log_text = "Ha fallado al ejecutar el cargo a %s por su aporte de %s mediante TPV (id: %s) al proyecto %s del dia %s <br />Se han dado los siguientes errores: $txt_errors";
  481. }
  482. *
  483. */
  484. break;
  485. case 'cash':
  486. // los cargos manuales no los modificamos
  487. if ($debug) echo ' Cash, nada que hacer -> Ok';
  488. break;
  489. }
  490. if ($debug) echo '<br />';
  491. if (!empty($log_text)) {
  492. // Evento Feed
  493. $log = new Feed();
  494. $log->setTarget($project->id);
  495. $log->populate('Cargo ejecutado (cron)', '/admin/invests', \vsprintf($log_text, array(
  496. Feed::item('user', $userData->name, $userData->id),
  497. Feed::item('money', $invest->amount.' &euro;'),
  498. Feed::item('system', $invest->id),
  499. Feed::item('project', $project->name, $project->id),
  500. Feed::item('system', date('d/m/Y', strtotime($invest->invested)))
  501. )));
  502. $log->doAdmin();
  503. if ($debug) echo $log->html . '<br />';
  504. unset($log);
  505. }
  506. if ($debug) echo 'Aporte '.$invest->id.' tratado<br />';
  507. }
  508. }
  509. if ($debug) echo '::Fin tratamiento aportes<br />';
  510. }
  511. if ($debug) echo 'Fin tratamiento Proyecto '.$project->name.'<hr />';
  512. }
  513. // checkeamos campañas activas
  514. $campaigns = Model\Call::getActive(4);
  515. foreach ($campaigns as $campaign) {
  516. $errors = array();
  517. // tiene que tener presupuesto
  518. if (empty($campaign->amount)) {
  519. continue;
  520. }
  521. // si le quedan cero
  522. // -> terminar la campaña exitosamente
  523. if ($campaign->rest == 0 && !empty($campaign->amount)) {
  524. echo 'La convocatoria '.$campaign->name.': ';
  525. if ($campaign->checkSuccess($errors)) {
  526. if ($campaign->succeed($errors)) {
  527. echo 'Ha terminado exitosamente.<br />';
  528. $log = new Feed();
  529. $log->setTarget($campaign->id, 'call');
  530. $log->unique = true;
  531. $log->populate('Campaña terminada (cron)', '/admin/calls/'.$campaign->id.'?rest='.$amount,
  532. \vsprintf('La campaña %s ha terminado con exito', array(
  533. Feed::item('call', $campaign->name, $campaign->id))
  534. ));
  535. $log->doAdmin('call');
  536. $log->populate($campaign->name, '/call/'.$campaign->id.'?rest='.$amount,
  537. \vsprintf('La campaña %s ha terminado con éxito', array(
  538. Feed::item('call', $campaign->name, $campaign->id))
  539. ), $call->logo);
  540. $log->doPublic('projects');
  541. unset($log);
  542. } else {
  543. echo 'Ha fallado al marcar exitosa.<br />'.implode('<br />', $errors);
  544. }
  545. } else {
  546. echo 'Le Queda algun proyecto en primera ronda.<br />';
  547. }
  548. }
  549. }
  550. // desbloqueamos
  551. if (unlink($block_file)) {
  552. echo 'Cron '. __FUNCTION__ .' desbloqueado<br />';
  553. } else {
  554. echo 'ALERT! Cron '. __FUNCTION__ .' no se ha podido desbloquear<br />';
  555. if(file_exists($block_file)) {
  556. echo 'El archivo '.$block_file.' aun existe!<br />';
  557. } else {
  558. echo 'No hay archivo de bloqueo '.$block_file.'!<br />';
  559. }
  560. }
  561. // recogemos el buffer para grabar el log
  562. $log_file = GOTEO_PATH.'logs/cron/'.date('Ymd').'_'.__FUNCTION__.'.log';
  563. \file_put_contents($log_file, \ob_get_contents(), FILE_APPEND);
  564. \chmod($log_file, 0777);
  565. }
  566. /*
  567. * Proceso que verifica si los preapprovals han sido coancelados
  568. * Solamente trata transacciones paypal pendientes de proyectos en campaña
  569. *
  570. */
  571. public function verify () {
  572. if (!\defined('CRON_EXEC')) {
  573. @mail(\GOTEO_FAIL_MAIL, 'Se ha lanzado el cron '. __FUNCTION__ .' en ' . SITE_URL,
  574. 'Se ha lanzado manualmente el cron '. __FUNCTION__ .' en ' . SITE_URL.' a las ' . date ('H:i:s') . ' Usuario '. $_SESSION['user']->id);
  575. echo 'Lanzamiento manual<br />';
  576. } else {
  577. echo 'Lanzamiento automatico<br />';
  578. }
  579. $debug = (isset($_GET['debug']) && $_GET['debug'] == 'debug') ? true : false;
  580. if ($debug) echo 'Modo debug activado<br />';
  581. // lanzamos subcontrolador
  582. Cron\Verify::process($debug);
  583. // también el tratamiento de geologin
  584. Cron\Geoloc::process($debug);
  585. // recogemos el buffer para grabar el log
  586. /*
  587. $log_file = GOTEO_PATH.'logs/cron/'.date('Ymd').'_'.__FUNCTION__.'.log';
  588. \file_put_contents($log_file, \ob_get_contents(), FILE_APPEND);
  589. \chmod($log_file, 0777);
  590. */
  591. die();
  592. }
  593. /*
  594. * Proceso que limpia la tabla de imágenes
  595. * y también limpia el directorio
  596. *
  597. */
  598. public function cleanup () {
  599. if (\defined('CRON_EXEC')) {
  600. @mail(\GOTEO_FAIL_MAIL, 'Se ha lanzado el cron '. __FUNCTION__ .' en ' . SITE_URL,
  601. 'Se intentaba lanzar automáticamente el cron '. __FUNCTION__ .' en ' . SITE_URL.' a las ' . date ('H:i:s') . ' Usuario '. $_SESSION['user']->id);
  602. die;
  603. } else {
  604. Cron\Cleanup::process();
  605. die();
  606. }
  607. }
  608. /*
  609. * Proceso para tratar los geologins
  610. *
  611. */
  612. public function geoloc () {
  613. // no necesito email de aviso por el momento
  614. /*
  615. if (!\defined('CRON_EXEC')) {
  616. @mail(\GOTEO_FAIL_MAIL, 'Se ha lanzado el cron '. __FUNCTION__ .' en ' . SITE_URL,
  617. 'Se ha lanzado manualmente el cron '. __FUNCTION__ .' en ' . SITE_URL.' a las ' . date ('H:i:s') . ' Usuario '. $_SESSION['user']->id);
  618. echo 'Lanzamiento manual<br />';
  619. } else {
  620. echo 'Lanzamiento automatico<br />';
  621. }
  622. */
  623. // lanzamos subcontrolador
  624. Cron\Geoloc::process();
  625. // Por el momento no grabamos log de esto, lo lanzamos manual
  626. /*
  627. $log_file = GOTEO_PATH.'logs/cron/'.date('Ymd').'_'.__FUNCTION__.'.log';
  628. \file_put_contents($log_file, \ob_get_contents(), FILE_APPEND);
  629. \chmod($log_file, 0777);
  630. */
  631. die();
  632. }
  633. /*
  634. * Realiza los pagos secundarios al proyecto
  635. *
  636. * Esto son los aportes de tipo paypal, ejecutados (status 1), que tengan payment code
  637. *
  638. */
  639. public function dopay ($project) {
  640. die('Ya no realizamos pagos secundarios mediante sistema');
  641. if (\defined('CRON_EXEC')) {
  642. die('Este proceso no necesitamos lanzarlo automaticamente');
  643. }
  644. @mail(\GOTEO_FAIL_MAIL, 'Se ha lanzado el cron '. __FUNCTION__ .' en ' . SITE_URL,
  645. 'Se ha lanzado manualmente el cron '. __FUNCTION__ .' para el proyecto '.$project.' en ' . SITE_URL.' a las ' . date ('H:i:s') . ' Usuario '. $_SESSION['user']->id);
  646. // a ver si existe el bloqueo
  647. $block_file = GOTEO_PATH.'logs/cron-'.__FUNCTION__.'.block';
  648. if (file_exists($block_file)) {
  649. echo 'Ya existe un archivo de log '.date('Ymd').'_'.__FUNCTION__.'.log<br />';
  650. $block_content = \file_get_contents($block_file);
  651. echo 'El contenido del bloqueo es: '.$block_content;
  652. // lo escribimos en el log
  653. $log_file = GOTEO_PATH.'logs/cron/'.date('Ymd').'_'.__FUNCTION__.'.log';
  654. \file_put_contents($log_file, \ob_get_contents(), FILE_APPEND);
  655. \chmod($log_file, 0777);
  656. /*
  657. @mail(\GOTEO_FAIL_MAIL, 'Cron '. __FUNCTION__ .' bloqueado en ' . SITE_URL,
  658. 'Se ha encontrado con que el cron '. __FUNCTION__ .' está bloqueado el '.date('d-m-Y').' a las ' . date ('H:i:s') . '
  659. El contenido del bloqueo es: '. $block_content);
  660. */
  661. die;
  662. } else {
  663. $block = 'Bloqueo '.$block_file.' activado el '.date('d-m-Y').' a las '.date ('H:i:s').'<br />';
  664. if (\file_put_contents($block_file, $block, FILE_APPEND)) {
  665. \chmod($block_file, 0777);
  666. echo $block;
  667. } else {
  668. echo 'No se ha podido crear el archivo de bloqueo<br />';
  669. @mail(\GOTEO_FAIL_MAIL, 'Cron '. __FUNCTION__ .' no se ha podido bloquear en ' . SITE_URL,
  670. 'No se ha podido crear el archivo '.$block_file.' el '.date('d-m-Y').' a las ' . date ('H:i:s'));
  671. }
  672. }
  673. $projectData = Model\Project::getMini($project);
  674. // necesitamos la cuenta del proyecto y que sea la misma que cuando el preapproval
  675. $projectAccount = Model\Project\Account::get($project);
  676. if (empty($projectAccount->paypal)) {
  677. // iniciamos mail
  678. $mailHandler = new Mail();
  679. $mailHandler->to = \GOTEO_MAIL;
  680. $mailHandler->toName = 'Goteo.org';
  681. $mailHandler->subject = 'El proyecto '.$projectData->name.' no tiene cuenta PayPal';
  682. $mailHandler->content = 'Hola Goteo, el proyecto '.$projectData->name.' no tiene cuenta PayPal y se estaba intentando realizar pagos secundarios.';
  683. $mailHandler->html = false;
  684. $mailHandler->template = null;
  685. $mailHandler->send();
  686. unset($mailHandler);
  687. die('El proyecto '.$projectData->name.' no tiene la cuenta PayPal!!');
  688. }
  689. // tratamiento de aportes pendientes
  690. $query = Model\Project::query("
  691. SELECT *
  692. FROM invest
  693. WHERE invest.status = 1
  694. AND invest.method = 'paypal'
  695. AND invest.project = ?
  696. ", array($project));
  697. $invests = $query->fetchAll(\PDO::FETCH_CLASS, '\Goteo\Model\Invest');
  698. echo 'Vamos a tratar ' . count($invests) . ' aportes para el proyecto '.$projectData->name.'<br />';
  699. foreach ($invests as $key=>$invest) {
  700. $errors = array();
  701. $userData = Model\User::getMini($invest->user);
  702. echo 'Tratando: Aporte (id: '.$invest->id.') de '.$userData->name.' ['.$userData->email.']<br />';
  703. if (Paypal::doPay($invest, $errors)) {
  704. echo 'Aporte (id: '.$invest->id.') pagado al proyecto. Ver los detalles en la <a href="/admin/accounts/details/'.$invest->id.'">gestion de transacciones</a><br />';
  705. $log_text = "Se ha realizado el pago de %s PayPal al proyecto %s por el aporte de %s (id: %s) del dia %s";
  706. Model\Invest::setDetail($invest->id, 'payed', 'Se ha realizado el pago secundario al proyecto. Proceso cron/doPay');
  707. } else {
  708. echo 'Fallo al pagar al proyecto el aporte (id: '.$invest->id.'). Ver los detalles en la <a href="/admin/accounts/details/'.$invest->id.'">gestion de transacciones</a><br />' . implode('<br />', $errors);
  709. $log_text = "Ha fallado al realizar el pago de %s PayPal al proyecto %s por el aporte de %s (id: %s) del dia %s";
  710. Model\Invest::setDetail($invest->id, 'pay-failed', 'Fallo al realizar el pago secundario: ' . implode('<br />', $errors) . '. Proceso cron/doPay');
  711. }
  712. // Evento Feed
  713. $log = new Feed();
  714. $log->setTarget($projectData->id);
  715. $log->populate('Pago al proyecto encadenado-secundario (cron)', '/admin/accounts',
  716. \vsprintf($log_text, array(
  717. Feed::item('money', $invest->amount.' &euro;'),
  718. Feed::item('project', $projectData->name, $project),
  719. Feed::item('user', $userData->name, $userData->id),
  720. Feed::item('system', $invest->id),
  721. Feed::item('system', date('d/m/Y', strtotime($invest->invested)))
  722. )));
  723. $log->doAdmin();
  724. unset($log);
  725. echo '<hr />';
  726. }
  727. // desbloqueamos
  728. if (unlink($block_file)) {
  729. echo 'Cron '. __FUNCTION__ .' desbloqueado<br />';
  730. } else {
  731. echo 'ALERT! Cron '. __FUNCTION__ .' no se ha podido desbloquear<br />';
  732. if(file_exists($block_file)) {
  733. echo 'El archivo '.$block_file.' aun existe!<br />';
  734. } else {
  735. echo 'No hay archivo de bloqueo '.$block_file.'!<br />';
  736. }
  737. }
  738. // recogemos el buffer para grabar el log
  739. $log_file = GOTEO_PATH.'logs/cron/'.date('Ymd').'_'.__FUNCTION__.'.log';
  740. \file_put_contents($log_file, \ob_get_contents(), FILE_APPEND);
  741. \chmod($log_file, 0777);
  742. }
  743. /**
  744. * Proceso para enviar avisos a los autores segun
  745. * - Que lleven 3 meses sin publicar actualizaciones, envia cada mes
  746. * - Que lleven 3 meses sin decir nada (?), envia cada 15 dias
  747. * - Que hayan pasado dos meses desde que se dio por financiado, cada 15 dias
  748. *
  749. * teiene en cuenta que se envía cada tantos días
  750. */
  751. public function daily () {
  752. if (!\defined('CRON_EXEC')) {
  753. @mail(\GOTEO_FAIL_MAIL, 'Se ha lanzado el cron '. __FUNCTION__ .' en ' . SITE_URL,
  754. 'Se ha lanzado manualmente el cron '. __FUNCTION__ .' en ' . SITE_URL.' a las ' . date ('H:i:s') . ' Usuario '. $_SESSION['user']->id);
  755. // die('Este proceso no necesitamos lanzarlo manualmente');
  756. }
  757. // temporalmente debug fijo (quitarlo al quitar monitorización)
  758. // $debug = (isset($_GET['debug']) && $_GET['debug'] == 'debug') ? true : false;
  759. $debug = true;
  760. if ($debug) echo 'Modo debug activado<br />';
  761. // subcontrolador Auto-tips
  762. Cron\Daily::Projects($debug);
  763. // subcontrolador progreso convocatorias
  764. Cron\Daily::Calls($debug);
  765. if ($debug) {
  766. // recogemos el buffer para grabar el log
  767. $log_file = GOTEO_PATH.'logs/cron/'.date('Ymd').'_'.__FUNCTION__.'.log';
  768. \file_put_contents($log_file, \ob_get_contents(), FILE_APPEND);
  769. \chmod($log_file, 0777);
  770. }
  771. }
  772. /*
  773. * Proceso que arregla las extensiones de los archivos de imágenes
  774. */
  775. public function imgrename () {
  776. if (\defined('CRON_EXEC')) {
  777. @mail(\GOTEO_FAIL_MAIL, 'Se ha lanzado el cron '. __FUNCTION__ .' en ' . SITE_URL,
  778. 'Se intentaba lanzar automáticamente el cron '. __FUNCTION__ .' en ' . SITE_URL.' a las ' .

Large files files are truncated, but you can click here to view the full file