]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/Schedulers/_AddJobsHere.php
Release 6.3.0
[Github/sugarcrm.git] / modules / Schedulers / _AddJobsHere.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM Community Edition is a customer relationship management program developed by
5  * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38
39 /**
40  * Set up an array of Jobs with the appropriate metadata
41  * 'jobName' => array (
42  *              'X' => 'name',
43  * )
44  * 'X' should be an increment of 1
45  * 'name' should be the EXACT name of your function
46  *
47  * Your function should not be passed any parameters
48  * Always  return a Boolean. If it does not the Job will not terminate itself
49  * after completion, and the webserver will be forced to time-out that Job instance.
50  * DO NOT USE sugar_cleanup(); in your function flow or includes.  this will
51  * break Schedulers.  That function is called at the foot of cron.php
52  */
53
54 /**
55  * This array provides the Schedulers admin interface with values for its "Job"
56  * dropdown menu.
57  */
58 $job_strings = array (
59         0 => 'refreshJobs',
60         1 => 'pollMonitoredInboxes',
61         2 => 'runMassEmailCampaign',
62     5 => 'pollMonitoredInboxesForBouncedCampaignEmails',
63         3 => 'pruneDatabase',
64         4 => 'trimTracker',
65         /*4 => 'securityAudit()',*/
66
67 );
68
69 /**
70  * Job 0 refreshes all job schedulers at midnight
71  * DEPRECATED
72  */
73 function refreshJobs() {
74         return true;
75 }
76
77
78 /**
79  * Job 1
80  */
81 function pollMonitoredInboxes() {
82
83         $GLOBALS['log']->info('----->Scheduler fired job of type pollMonitoredInboxes()');
84         global $dictionary;
85         global $app_strings;
86         
87         
88         require_once('modules/Emails/EmailUI.php');
89
90         $ie = new InboundEmail();
91         $emailUI = new EmailUI();
92         $r = $ie->db->query('SELECT id, name FROM inbound_email WHERE is_personal = 0 AND deleted=0 AND status=\'Active\' AND mailbox_type != \'bounce\'');
93         $GLOBALS['log']->debug('Just got Result from get all Inbounds of Inbound Emails');
94
95         while($a = $ie->db->fetchByAssoc($r)) {
96                 $GLOBALS['log']->debug('In while loop of Inbound Emails');
97                 $ieX = new InboundEmail();
98                 $ieX->retrieve($a['id']);
99                 $mailboxes = $ieX->mailboxarray;
100                 foreach($mailboxes as $mbox) {
101                         $ieX->mailbox = $mbox;
102                         $newMsgs = array();
103                         $msgNoToUIDL = array();
104                         $connectToMailServer = false;
105                         if ($ieX->isPop3Protocol()) {
106                                 $msgNoToUIDL = $ieX->getPop3NewMessagesToDownloadForCron();
107                                 // get all the keys which are msgnos;
108                                 $newMsgs = array_keys($msgNoToUIDL);
109                         }
110                         if($ieX->connectMailserver() == 'true') {
111                                 $connectToMailServer = true;
112                         } // if
113
114                         $GLOBALS['log']->debug('Trying to connect to mailserver for [ '.$a['name'].' ]');
115                         if($connectToMailServer) {
116                                 $GLOBALS['log']->debug('Connected to mailserver');
117                                 if (!$ieX->isPop3Protocol()) {
118                                         $newMsgs = $ieX->getNewMessageIds();
119                                 }
120                                 if(is_array($newMsgs)) {
121                                         $current = 1;
122                                         $total = count($newMsgs);
123                                         require_once("include/SugarFolders/SugarFolders.php");
124                                         $sugarFolder = new SugarFolder();
125                                         $groupFolderId = $ieX->groupfolder_id;
126                                         $isGroupFolderExists = false;
127                                         $users = array();
128                                         if ($groupFolderId != null && $groupFolderId != "") {
129                                                 $sugarFolder->retrieve($groupFolderId);
130                                                 $isGroupFolderExists = true;
131                                         } // if
132                                         $messagesToDelete = array();
133                                         if ($ieX->isMailBoxTypeCreateCase()) {
134                                                 $users[] = $sugarFolder->assign_to_id;
135                                                 $distributionMethod = $ieX->get_stored_options("distrib_method", "");
136                                                 if ($distributionMethod != 'roundRobin') {
137                                                         $counts = $emailUI->getAssignedEmailsCountForUsers($users);
138                                                 } else {
139                                                         $lastRobin = $emailUI->getLastRobin($ieX);
140                                                 }
141                                                 $GLOBALS['log']->debug('distribution method id [ '.$distributionMethod.' ]');
142                                         }
143                                         foreach($newMsgs as $k => $msgNo) {
144                                                 $uid = $msgNo;
145                                                 if ($ieX->isPop3Protocol()) {
146                                                         $uid = $msgNoToUIDL[$msgNo];
147                                                 } else {
148                                                         $uid = imap_uid($ieX->conn, $msgNo);
149                                                 } // else
150                                                 if ($isGroupFolderExists) {
151                                                         if ($ieX->importOneEmail($msgNo, $uid)) {
152                                                                 // add to folder
153                                                                 $sugarFolder->addBean($ieX->email);
154                                                                 if ($ieX->isPop3Protocol()) {
155                                                                         $messagesToDelete[] = $msgNo;
156                                                                 } else {
157                                                                         $messagesToDelete[] = $uid;
158                                                                 }
159                                                                 if ($ieX->isMailBoxTypeCreateCase()) {
160                                                                         $userId = "";
161                                                                         if ($distributionMethod == 'roundRobin') {
162                                                                                 if (sizeof($users) == 1) {
163                                                                                         $userId = $users[0];
164                                                                                         $lastRobin = $users[0];
165                                                                                 } else {
166                                                                                         $userIdsKeys = array_flip($users); // now keys are values
167                                                                                         $thisRobinKey = $userIdsKeys[$lastRobin] + 1;
168                                                                                         if(!empty($users[$thisRobinKey])) {
169                                                                                                 $userId = $users[$thisRobinKey];
170                                                                                                 $lastRobin = $users[$thisRobinKey];
171                                                                                         } else {
172                                                                                                 $userId = $users[0];
173                                                                                                 $lastRobin = $users[0];
174                                                                                         }
175                                                                                 } // else
176                                                                         } else {
177                                                                                 if (sizeof($users) == 1) {
178                                                                                         foreach($users as $k => $value) {
179                                                                                                 $userId = $value;
180                                                                                         } // foreach
181                                                                                 } else {
182                                                                                         asort($counts); // lowest to highest
183                                                                                         $countsKeys = array_flip($counts); // keys now the 'count of items'
184                                                                                         $leastBusy = array_shift($countsKeys); // user id of lowest item count
185                                                                                         $userId = $leastBusy;
186                                                                                         $counts[$leastBusy] = $counts[$leastBusy] + 1;
187                                                                                 }
188                                                                         } // else
189                                                                         $GLOBALS['log']->debug('userId [ '.$userId.' ]');
190                                                                         $ieX->handleCreateCase($ieX->email, $userId);
191                                                                 } // if
192                                                         } // if
193                                                 } else {
194                                                                 if($ieX->isAutoImport()) {
195                                                                         $ieX->importOneEmail($msgNo, $uid);
196                                                                 } else {
197                                                                         /*If the group folder doesn't exist then download only those messages
198                                                                          which has caseid in message*/
199                                                                         $ieX->getMessagesInEmailCache($msgNo, $uid);
200                                                                         $email = new Email();
201                                                                         $header = imap_headerinfo($ieX->conn, $msgNo);
202                                                                         $email->name = $ieX->handleMimeHeaderDecode($header->subject);
203                                                                         $email->from_addr = $ieX->convertImapToSugarEmailAddress($header->from);
204                                                                         $email->reply_to_email  = $ieX->convertImapToSugarEmailAddress($header->reply_to);
205                                                                         if(!empty($email->reply_to_email)) {
206                                                                                 $contactAddr = $email->reply_to_email;
207                                                                         } else {
208                                                                                 $contactAddr = $email->from_addr;
209                                                                         }
210                                                                         $mailBoxType = $ieX->mailbox_type;
211                                                                                 $ieX->handleAutoresponse($email, $contactAddr);
212                                                                 } // else
213                                                 } // else
214                                                 $GLOBALS['log']->debug('***** On message [ '.$current.' of '.$total.' ] *****');
215                                                 $current++;
216                                         } // foreach
217                                         // update Inbound Account with last robin
218                                         if ($ieX->isMailBoxTypeCreateCase() && $distributionMethod == 'roundRobin') {
219                                                 $emailUI->setLastRobin($ieX, $lastRobin);
220                                         } // if
221
222                                 } // if
223                                 if ($isGroupFolderExists)        {
224                                         $leaveMessagesOnMailServer = $ieX->get_stored_options("leaveMessagesOnMailServer", 0);
225                                         if (!$leaveMessagesOnMailServer) {
226                                                 if ($ieX->isPop3Protocol()) {
227                                                         $ieX->deleteMessageOnMailServerForPop3(implode(",", $messagesToDelete));
228                                                 } else {
229                                                         $ieX->deleteMessageOnMailServer(implode($app_strings['LBL_EMAIL_DELIMITER'], $messagesToDelete));
230                                                 }
231                                         }
232                                 }
233                         } else {
234                                 $GLOBALS['log']->fatal("SCHEDULERS: could not get an IMAP connection resource for ID [ {$a['id']} ]. Skipping mailbox [ {$a['name']} ].");
235                                 // cn: bug 9171 - continue while
236                         } // else
237                 } // foreach
238                 imap_expunge($ieX->conn);
239                 imap_close($ieX->conn, CL_EXPUNGE);
240         } // while
241
242         return true;
243 }
244
245 /**
246  * Job 2
247  */
248 function runMassEmailCampaign() {
249         if (!class_exists('LoggerManager')){
250                 
251         }
252         $GLOBALS['log'] = LoggerManager::getLogger('emailmandelivery');
253         $GLOBALS['log']->debug('Called:runMassEmailCampaign');
254
255         if (!class_exists('DBManagerFactory')){
256                 require('include/database/DBManagerFactory.php');
257         }
258         
259         global $beanList;
260         global $beanFiles;
261         require("config.php");
262         require('include/modules.php');
263         if(!class_exists('AclController')) {
264                 require('modules/ACL/ACLController.php');
265         }
266
267         require('modules/EmailMan/EmailManDelivery.php');
268         return true;
269 }
270
271 /**
272  *  Job 3
273  */
274 function pruneDatabase() {
275         $GLOBALS['log']->info('----->Scheduler fired job of type pruneDatabase()');
276         $backupDir      = $GLOBALS['sugar_config']['cache_dir'].'backups';
277         $backupFile     = 'backup-pruneDatabase-GMT0_'.gmdate('Y_m_d-H_i_s', strtotime('now')).'.php';
278
279         $db = DBManagerFactory::getInstance();
280         $tables = $db->getTablesArray();
281
282 //_ppd($tables);
283         if(!empty($tables)) {
284                 foreach($tables as $kTable => $table) {
285                         // find tables with deleted=1
286                         $qDel = 'SELECT * FROM '.$table.' WHERE deleted = 1';
287                         $rDel = $db->query($qDel);// OR continue; // continue if no 'deleted' column
288
289                         // make a backup INSERT query if we are deleting.
290                         while($aDel = $db->fetchByAssoc($rDel)) {
291                                 // build column names
292                                 $rCols = $db->query('SHOW COLUMNS FROM '.$table);
293                                 $colName = array();
294
295                                 while($aCols = $db->fetchByAssoc($rCols)) {
296                                         $colName[] = $aCols['Field'];
297                                 }
298
299                                 $query = 'INSERT INTO '.$table.' (';
300                                 $values = '';
301                                 foreach($colName as $kC => $column) {
302                                         $query .= $column.', ';
303                                         $values .= '"'.$aDel[$column].'", ';
304                                 }
305
306                                 $query  = substr($query, 0, (strlen($query) - 2));
307                                 $values = substr($values, 0, (strlen($values) - 2));
308                                 $query .= ') VALUES ('.str_replace("'", "&#039;", $values).');';
309
310                                 $queryString[] = $query;
311
312                                 if(empty($colName)) {
313                                         $GLOBALS['log']->fatal('pruneDatabase() could not get the columns for table ('.$table.')');
314                                 }
315                                 
316                                 if(array_search($table.'_cstm', $tables) !== FALSE && array_search('id', $colName) !== FALSE && array_key_exists('id', $aDel)) {
317                     // build custom column names
318                     $rColsCstm = $db->query('SHOW COLUMNS FROM '.$table.'_cstm');
319                     $colNameCstm = array();
320
321                     while($aColsCstm = $db->fetchByAssoc($rColsCstm)) {
322                         $colNameCstm[] = $aColsCstm['Field'];
323                     }
324
325                     $qDelCstm = 'SELECT * FROM '.$table.'_cstm WHERE id_c = "'.$db->quote($aDel['id']).'"';
326                     $rDelCstm = $db->query($qDelCstm);// OR continue; // continue if no 'deleted' column
327
328                     // make a backup INSERT query if we are deleting.
329                     while($aDelCstm = $db->fetchByAssoc($rDelCstm)) {
330
331                         $query = 'INSERT INTO '.$table.'_cstm (';
332                         $values = '';
333
334                         foreach($colNameCstm as $kC => $column) {
335                             $query .= $column.', ';
336                             $values .= '"'.$aDelCstm[$column].'", ';
337                         }
338
339                         $query  = substr($query, 0, (strlen($query) - 2));
340                         $values = substr($values, 0, (strlen($values) - 2));
341                         $query .= ') VALUES ('.str_replace("'", "&#039;", $values).');';
342
343                         $queryString[] = $query;
344
345                         if(empty($colNameCstm)) {
346                             $GLOBALS['log']->fatal('pruneDatabase() could not get the columns for table ('.$table.'_cstm)');
347                         }
348                     } // end aDel while()                
349
350                     $db->query('DELETE FROM '.$table.'_cstm WHERE id_c = "'.$db->quote($aDel['id']).'"');
351                 }
352                         } // end aDel while()
353                         // now do the actual delete
354                         $db->query('DELETE FROM '.$table.' WHERE deleted = 1');
355                 } // foreach() tables
356
357                 if(!file_exists($backupDir) || !file_exists($backupDir.'/'.$backupFile)) {
358                         // create directory if not existent
359                         mkdir_recursive($backupDir, false);
360                 }
361                 // write cache file
362
363                 write_array_to_file('pruneDatabase', $queryString, $backupDir.'/'.$backupFile);
364                 return true;
365         }
366         return false;
367 }
368
369
370 ///**
371 // * Job 4
372 // */
373
374 //function securityAudit() {
375 //      // do something
376 //      return true;
377 //}
378
379 function trimTracker()
380 {
381     global $sugar_config, $timedate;
382         $GLOBALS['log']->info('----->Scheduler fired job of type trimTracker()');
383         $db = DBManagerFactory::getInstance();
384         
385         $admin = new Administration();
386         $admin->retrieveSettings('tracker');
387         require('modules/Trackers/config.php');
388         $trackerConfig = $tracker_config;
389
390     require_once('include/utils/db_utils.php');
391     $prune_interval = !empty($admin->settings['tracker_prune_interval']) ? $admin->settings['tracker_prune_interval'] : 30;
392         foreach($trackerConfig as $tableName=>$tableConfig) {
393
394                 //Skip if table does not exist
395                 if(!$db->tableExists($tableName)) {
396                    continue;
397                 }
398
399             $timeStamp = db_convert("'". $timedate->asDb($timedate->getNow()->get("+"+$prune_interval+" days")) ."'" ,"datetime");
400                 if($tableName == 'tracker_sessions') {
401                    $query = "DELETE FROM $tableName WHERE date_end < $timeStamp";
402                 } else {
403                    $query = "DELETE FROM $tableName WHERE date_modified < $timeStamp";
404                 }
405
406             $GLOBALS['log']->info("----->Scheduler is about to trim the $tableName table by running the query $query");
407                 $db->query($query);
408         } //foreach
409     return true;
410 }
411
412 /* Job 5
413  *
414  */
415 function pollMonitoredInboxesForBouncedCampaignEmails() {
416         $GLOBALS['log']->info('----->Scheduler job of type pollMonitoredInboxesForBouncedCampaignEmails()');
417         global $dictionary;
418         
419
420         $ie = new InboundEmail();
421         $r = $ie->db->query('SELECT id FROM inbound_email WHERE deleted=0 AND status=\'Active\' AND mailbox_type=\'bounce\'');
422
423         while($a = $ie->db->fetchByAssoc($r)) {
424                 $ieX = new InboundEmail();
425                 $ieX->retrieve($a['id']);
426                 $ieX->connectMailserver();
427         $GLOBALS['log']->info("Bounced campaign scheduler connected to mail server id: {$a['id']} ");
428                 $newMsgs = array();
429                 if ($ieX->isPop3Protocol()) {
430                         $newMsgs = $ieX->getPop3NewMessagesToDownload();
431                 } else {
432                         $newMsgs = $ieX->getNewMessageIds();
433                 }
434
435                 //$newMsgs = $ieX->getNewMessageIds();
436                 if(is_array($newMsgs)) {
437                         foreach($newMsgs as $k => $msgNo) {
438                                 $uid = $msgNo;
439                                 if ($ieX->isPop3Protocol()) {
440                                         $uid = $ieX->getUIDLForMessage($msgNo);
441                                 } else {
442                                         $uid = imap_uid($ieX->conn, $msgNo);
443                                 } // else
444                  $GLOBALS['log']->info("Bounced campaign scheduler will import message no: $msgNo");
445                                 $ieX->importOneEmail($msgNo, $uid, false,false);
446                         }
447                 }
448                 imap_expunge($ieX->conn);
449                 imap_close($ieX->conn);
450         }
451
452         return true;
453 }
454
455
456
457
458
459 if (file_exists('custom/modules/Schedulers/_AddJobsHere.php')) {
460         require('custom/modules/Schedulers/_AddJobsHere.php');
461 }
462
463 if (file_exists('custom/modules/Schedulers/Ext/ScheduledTasks/scheduledtasks.ext.php'))
464 {
465         require('custom/modules/Schedulers/Ext/ScheduledTasks/scheduledtasks.ext.php');
466 }
467 ?>