PageRenderTime 53ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/plugins/cerb5blog.watchers2/api/App.php

https://github.com/rmiddle/cerb4_plugins
PHP | 1540 lines | 1085 code | 289 blank | 166 comment | 164 complexity | 8893d624dec9c82abf40ebdea5157dc7 MD5 | raw file
  1. <?php
  2. class Cerb5blogWatchers2ConfigTab extends Extension_ConfigTab {
  3. const ID = 'cerb5blog.watchers2.config.tab';
  4. function showTab() {
  5. $settings = CerberusSettings::getInstance();
  6. $tpl = DevblocksPlatform::getTemplateService();
  7. $tpl_path = dirname(dirname(__FILE__)) . '/templates/';
  8. $core_tplpath = dirname(dirname(dirname(__FILE__))) . '/cerberusweb.core/templates/';
  9. $tpl->assign('core_tplpath', $core_tplpath);
  10. $tpl->cache_lifetime = "0";
  11. $tpl->assign('response_uri', 'config/watchers2');
  12. $defaults = new C4_AbstractViewModel();
  13. $defaults->class_name = 'C4_Watcher2View';
  14. $defaults->id = C4_Watcher2View::DEFAULT_ID;
  15. $defaults->renderSortBy = SearchFields_Watcher2MailFilter::POS;
  16. $defaults->renderSortAsc = 0;
  17. $view = C4_AbstractViewLoader::getView(C4_Watcher2View::DEFAULT_ID, $defaults);
  18. $tpl->assign('view', $view);
  19. $tpl->assign('view_fields', C4_Watcher2View::getFields());
  20. $tpl->assign('view_searchable_fields', C4_Watcher2View::getSearchFields());
  21. $tpl->display('file:' . $tpl_path . 'config/watchers2/index.tpl');
  22. }
  23. function saveTab() {
  24. @$plugin_id = DevblocksPlatform::importGPC($_REQUEST['plugin_id'],'string');
  25. DevblocksPlatform::redirect(new DevblocksHttpResponse(array('config','watchers2')));
  26. exit;
  27. }
  28. };
  29. class Cerb5blogWatchers2Preferences extends Extension_PreferenceTab {
  30. private $_TPL_PATH = null;
  31. function __construct($manifest) {
  32. parent::__construct($manifest);
  33. $this->_TPL_PATH = dirname(dirname(__FILE__)).'/templates/';
  34. }
  35. // Ajax
  36. function showTab() {
  37. $tpl = DevblocksPlatform::getTemplateService();
  38. $tpl->assign('path', $this->_TPL_PATH);
  39. $tpl->cache_lifetime = "0";
  40. $worker = CerberusApplication::getActiveWorker();
  41. $workers = DAO_Worker::getAll();
  42. $tpl->assign('workers', $workers);
  43. $tpl->assign('response_uri', 'preferences/watchers2');
  44. if(null == ($view = C4_AbstractViewLoader::getView('prefs.watchers2'))) {
  45. $view = new C4_Watcher2View();
  46. $view->id = 'prefs.watchers2';
  47. $view->name = "My Watcher 2.0 Filters";
  48. $view->renderSortBy = SearchFields_Watcher2MailFilter::POS;
  49. $view->renderSortAsc = 0;
  50. $view->params = array(
  51. SearchFields_Watcher2MailFilter::WORKER_ID => new DevblocksSearchCriteria(SearchFields_Watcher2MailFilter::WORKER_ID,'eq',$worker->id),
  52. );
  53. C4_AbstractViewLoader::setView($view->id, $view);
  54. }
  55. $tpl->assign('view', $view);
  56. $tpl->assign('view_fields', C4_Watcher2View::getFields());
  57. $tpl->assign('view_searchable_fields', C4_Watcher2View::getSearchFields());
  58. $tpl->display('file:' . $this->_TPL_PATH . 'preferences/watchers2.tpl');
  59. }
  60. // Post
  61. function saveTab() {
  62. }
  63. // Ajax
  64. function showWatcher2BulkPanelAction() {
  65. @$id_csv = DevblocksPlatform::importGPC($_REQUEST['ids']);
  66. @$view_id = DevblocksPlatform::importGPC($_REQUEST['view_id']);
  67. $tpl = DevblocksPlatform::getTemplateService();
  68. $path = dirname(dirname(__FILE__)) . '/templates/';
  69. $tpl->assign('path', $path);
  70. $tpl->assign('view_id', $view_id);
  71. if(!empty($id_csv)) {
  72. $ids = DevblocksPlatform::parseCsvString($id_csv);
  73. $tpl->assign('ids', implode(',', $ids));
  74. }
  75. // Custom Fields
  76. // $custom_fields = DAO_CustomField::getBySource(ChCustomFieldSource_TimeEntry::ID);
  77. // $tpl->assign('custom_fields', $custom_fields);
  78. $tpl->cache_lifetime = "0";
  79. $tpl->display('file:' . $path . 'preferences/bulk.tpl');
  80. }
  81. // Ajax
  82. function doWatcher2BulkPanelAction() {
  83. // Checked rows
  84. @$ids_str = DevblocksPlatform::importGPC($_REQUEST['ids'],'string');
  85. $ids = DevblocksPlatform::parseCsvString($ids_str);
  86. // Filter: whole list or check
  87. @$filter = DevblocksPlatform::importGPC($_REQUEST['filter'],'string','');
  88. // View
  89. @$view_id = DevblocksPlatform::importGPC($_REQUEST['view_id'],'string');
  90. $view = C4_AbstractViewLoader::getView($view_id);
  91. // Watcher2 fields
  92. @$status = trim(DevblocksPlatform::importGPC($_POST['do_status'],'string',''));
  93. $do = array();
  94. // Do: ...
  95. if(0 != strlen($status))
  96. $do['status'] = intval($status);
  97. // Do: Custom fields
  98. //$do = DAO_CustomFieldValue::handleBulkPost($do);
  99. $view->doBulkUpdate($filter, $do, $ids);
  100. $view->render();
  101. return;
  102. }
  103. // Ajax
  104. function showWatcher2PanelAction() {
  105. @$id = DevblocksPlatform::importGPC($_REQUEST['id'],'integer',0);
  106. $tpl = DevblocksPlatform::getTemplateService();
  107. $tpl->cache_lifetime = "0";
  108. $tpl->assign('path', $this->_TPL_PATH);
  109. $active_worker = CerberusApplication::getActiveWorker();
  110. if(null != ($filter = DAO_Watcher2MailFilter::get($id))) {
  111. $tpl->assign('filter', $filter);
  112. }
  113. $groups = DAO_Group::getAll();
  114. $tpl->assign('groups', $groups);
  115. $buckets = DAO_Bucket::getAll();
  116. $tpl->assign('buckets', $buckets);
  117. $group_buckets = DAO_Bucket::getTeams();
  118. $tpl->assign('group_buckets', $group_buckets);
  119. $memberships = $active_worker->getMemberships();
  120. $tpl->assign('memberships', $memberships);
  121. if(null == (@$worker_id = $filter->worker_id)) {
  122. $worker_id = $active_worker->id;
  123. }
  124. $addresses = DAO_AddressToWorker::getByWorker($worker_id);
  125. $tpl->assign('addresses', $addresses);
  126. $tpl->assign('workers', DAO_Worker::getAllActive());
  127. $tpl->assign('all_workers', DAO_Worker::getAll());
  128. // Custom Fields: Ticket
  129. $ticket_fields = DAO_CustomField::getBySource(ChCustomFieldSource_Ticket::ID);
  130. $tpl->assign('ticket_fields', $ticket_fields);
  131. // Custom Fields: Address
  132. $address_fields = DAO_CustomField::getBySource(ChCustomFieldSource_Address::ID);
  133. $tpl->assign('address_fields', $address_fields);
  134. // Custom Fields: Orgs
  135. $org_fields = DAO_CustomField::getBySource(ChCustomFieldSource_Org::ID);
  136. $tpl->assign('org_fields', $org_fields);
  137. $tpl->display('file:' . $this->_TPL_PATH . 'preferences/peek.tpl');
  138. }
  139. function saveWatcher2PanelAction() {
  140. $translate = DevblocksPlatform::getTranslationService();
  141. @$id = DevblocksPlatform::importGPC($_REQUEST['id'],'integer',0);
  142. @$active_worker = CerberusApplication::getActiveWorker();
  143. // if(!$active_worker->is_superuser)
  144. // return;
  145. /*****************************/
  146. @$name = DevblocksPlatform::importGPC($_POST['name'],'string','');
  147. @$is_disabled = DevblocksPlatform::importGPC($_POST['is_disabled'],'integer',0);
  148. @$worker_id = DevblocksPlatform::importGPC($_POST['worker_id'],'integer',0);
  149. @$rules = DevblocksPlatform::importGPC($_POST['rules'],'array',array());
  150. @$do = DevblocksPlatform::importGPC($_POST['do'],'array',array());
  151. if(empty($name))
  152. $name = $translate->_('watcher2.ui.pref.filters');
  153. $criterion = array();
  154. $actions = array();
  155. // Custom fields
  156. $custom_fields = DAO_CustomField::getAll();
  157. // Criteria
  158. if(is_array($rules))
  159. foreach($rules as $rule) {
  160. $rule = DevblocksPlatform::strAlphaNumDash($rule);
  161. @$value = DevblocksPlatform::importGPC($_POST['value_'.$rule],'string','');
  162. // [JAS]: Allow empty $value (null/blank checking)
  163. $criteria = array(
  164. 'value' => $value,
  165. );
  166. // Any special rule handling
  167. switch($rule) {
  168. case 'dayofweek':
  169. // days
  170. $days = DevblocksPlatform::importGPC($_REQUEST['value_dayofweek'],'array',array());
  171. if(in_array(0,$days)) $criteria['sun'] = $translate->_('watcher2.dow.sunday');
  172. if(in_array(1,$days)) $criteria['mon'] = $translate->_('watcher2.dow.monday');
  173. if(in_array(2,$days)) $criteria['tue'] = $translate->_('watcher2.dow.tuesday');
  174. if(in_array(3,$days)) $criteria['wed'] = $translate->_('watcher2.dow.wednesday');
  175. if(in_array(4,$days)) $criteria['thu'] = $translate->_('watcher2.dow.thursday');
  176. if(in_array(5,$days)) $criteria['fri'] = $translate->_('watcher2.dow.friday');
  177. if(in_array(6,$days)) $criteria['sat'] = $translate->_('watcher2.dow.saturday');
  178. unset($criteria['value']);
  179. break;
  180. case 'timeofday':
  181. $from = DevblocksPlatform::importGPC($_REQUEST['timeofday_from'],'string','');
  182. $to = DevblocksPlatform::importGPC($_REQUEST['timeofday_to'],'string','');
  183. $criteria['from'] = $from;
  184. $criteria['to'] = $to;
  185. unset($criteria['value']);
  186. break;
  187. case 'event':
  188. @$events = DevblocksPlatform::importGPC($_REQUEST['value_event'],'array',array());
  189. if(is_array($events))
  190. foreach($events as $event)
  191. $criteria[$event] = true;
  192. unset($criteria['value']);
  193. break;
  194. case 'groups':
  195. @$groups = DevblocksPlatform::importGPC($_REQUEST['value_groups'],'array',array());
  196. if(is_array($groups) && !empty($groups)) {
  197. $criteria['groups'] = array();
  198. foreach($groups as $group_id) {
  199. @$all = DevblocksPlatform::importGPC($_REQUEST['value_group'.$group_id.'_all'],'integer',0);
  200. // Did we only want to watch specific buckets in this group?
  201. $bucket_ids = array();
  202. if(!$all)
  203. @$bucket_ids = DevblocksPlatform::importGPC($_REQUEST['value_group'.$group_id.'_buckets'],'array',array());
  204. // Add to criteria (key=group id, val=array of bucket ids)
  205. $criteria['groups'][$group_id] = $bucket_ids;
  206. }
  207. }
  208. unset($criteria['value']);
  209. break;
  210. case 'next_worker_id':
  211. break;
  212. case 'subject':
  213. break;
  214. case 'from':
  215. break;
  216. // case 'tocc':
  217. // break;
  218. case 'header1':
  219. case 'header2':
  220. case 'header3':
  221. case 'header4':
  222. case 'header5':
  223. if(null != (@$header = DevblocksPlatform::importGPC($_POST[$rule],'string',null)))
  224. $criteria['header'] = strtolower($header);
  225. break;
  226. case 'body':
  227. break;
  228. default: // ignore invalids // [TODO] Very redundant
  229. // Custom fields
  230. if("cf_" == substr($rule,0,3)) {
  231. $field_id = intval(substr($rule,3));
  232. if(!isset($custom_fields[$field_id]))
  233. continue;
  234. // [TODO] Operators
  235. switch($custom_fields[$field_id]->type) {
  236. case 'S': // string
  237. case 'T': // clob
  238. case 'U': // URL
  239. @$oper = DevblocksPlatform::importGPC($_REQUEST['value_cf_'.$field_id.'_oper'],'string','regexp');
  240. $criteria['oper'] = $oper;
  241. break;
  242. case 'D': // dropdown
  243. case 'M': // multi-dropdown
  244. case 'X': // multi-checkbox
  245. case 'W': // worker
  246. @$in_array = DevblocksPlatform::importGPC($_REQUEST['value_cf_'.$field_id],'array',array());
  247. $out_array = array();
  248. // Hash key on the option for quick lookup later
  249. if(is_array($in_array))
  250. foreach($in_array as $k => $v) {
  251. $out_array[$v] = $v;
  252. }
  253. $criteria['value'] = $out_array;
  254. break;
  255. case 'E': // date
  256. @$from = DevblocksPlatform::importGPC($_REQUEST['value_cf_'.$field_id.'_from'],'string','0');
  257. @$to = DevblocksPlatform::importGPC($_REQUEST['value_cf_'.$field_id.'_to'],'string','now');
  258. $criteria['from'] = $from;
  259. $criteria['to'] = $to;
  260. unset($criteria['value']);
  261. break;
  262. case 'N': // number
  263. @$oper = DevblocksPlatform::importGPC($_REQUEST['value_cf_'.$field_id.'_oper'],'string','=');
  264. $criteria['oper'] = $oper;
  265. $criteria['value'] = intval($value);
  266. break;
  267. case 'C': // checkbox
  268. $criteria['value'] = intval($value);
  269. break;
  270. }
  271. } else {
  272. continue;
  273. }
  274. break;
  275. }
  276. $criterion[$rule] = $criteria;
  277. }
  278. // Actions
  279. if(is_array($do))
  280. foreach($do as $act) {
  281. $action = array();
  282. switch($act) {
  283. // Forward a copy to...
  284. case 'email':
  285. @$emails = DevblocksPlatform::importGPC($_REQUEST['do_email'],'array',array());
  286. if(!empty($emails)) {
  287. $action = array(
  288. 'to' => $emails
  289. );
  290. }
  291. break;
  292. // Watcher2 notification
  293. case 'notify':
  294. //@$emails = DevblocksPlatform::importGPC($_REQUEST['do_email'],'array',array());
  295. //if(!empty($emails)) {
  296. $action = array(
  297. //'to' => $emails
  298. );
  299. //}
  300. break;
  301. }
  302. $actions[$act] = $action;
  303. }
  304. $fields = array(
  305. DAO_Watcher2MailFilter::NAME => $name,
  306. DAO_Watcher2MailFilter::IS_DISABLED => $is_disabled,
  307. DAO_Watcher2MailFilter::WORKER_ID => $worker_id,
  308. DAO_Watcher2MailFilter::CRITERIA_SER => serialize($criterion),
  309. DAO_Watcher2MailFilter::ACTIONS_SER => serialize($actions),
  310. );
  311. // Create
  312. if(empty($id)) {
  313. $fields[DAO_Watcher2MailFilter::POS] = 0;
  314. $id = DAO_Watcher2MailFilter::create($fields);
  315. // Update
  316. } else {
  317. DAO_Watcher2MailFilter::update($id, $fields);
  318. }
  319. exit;
  320. //DevblocksPlatform::redirect(new DevblocksHttpResponse(array('preferences','watchers2')));
  321. }
  322. function getWorkerAddressesAction() {
  323. @$worker_id = DevblocksPlatform::importGPC($_REQUEST['worker_id'],'integer',0);
  324. $tpl = DevblocksPlatform::getTemplateService();
  325. $tpl->cache_lifetime = "0";
  326. $tpl->assign('path', $this->_TPL_PATH);
  327. $addresses = DAO_AddressToWorker::getByWorker($worker_id);
  328. $tpl->assign('addresses', $addresses);
  329. $tpl->display('file:' . $this->_TPL_PATH . 'preferences/worker_addresses.tpl');
  330. }
  331. /*
  332. Type List.
  333. 1 = Assigned
  334. 2 = Comment
  335. 3 = Inbound
  336. 4 = Outbound
  337. 5 = Moved
  338. */
  339. // Ajax
  340. function showTemplatesPanelAction() {
  341. @$type = DevblocksPlatform::importGPC($_REQUEST['type'],'integer',0);
  342. $tpl = DevblocksPlatform::getTemplateService();
  343. $tpl->assign('path', $this->_TPL_PATH);
  344. $tpl->assign('template_type', $template_type);
  345. $tpl->assign('tpl_path', $this->_TPL_PATH);
  346. $where = null;
  347. if(empty($templates_list)) {
  348. $where = sprintf("%s = %d",
  349. DAO_Watcher2Template::TEMPLATE_TYPE,
  350. $type
  351. );
  352. }
  353. $templates = DAO_Watcher2Template::getWhere($where);
  354. $tpl->assign('templates', $templates);
  355. $tpl->display('file:' . $this->_TPL_PATH . 'watcher2_template/templates_panel.tpl');
  356. }
  357. // Ajax
  358. function showTemplateEditPanelAction() {
  359. @$id = DevblocksPlatform::importGPC($_REQUEST['id'],'integer');
  360. @$template_type = DevblocksPlatform::importGPC($_REQUEST['type'],'integer',0);
  361. $tpl = DevblocksPlatform::getTemplateService();
  362. $tpl->assign('path', $this->_TPL_PATH);
  363. $tpl->assign('template_type', $template_type);
  364. $template = DAO_Watcher2Template::get($id);
  365. $tpl->assign('template', $template);
  366. $tpl->display('file:' . $this->_TPL_PATH . 'watcher2_template/template_edit_panel.tpl');
  367. }
  368. // Ajax
  369. function saveWatcher2TemplateAction() {
  370. @$id = DevblocksPlatform::importGPC($_REQUEST['id'],'integer',0);
  371. @$title = DevblocksPlatform::importGPC($_REQUEST['title'],'string','');
  372. @$description = DevblocksPlatform::importGPC($_REQUEST['description'],'string','');
  373. @$template_type = DevblocksPlatform::importGPC($_REQUEST['template_type'],'integer',0);
  374. @$subject = DevblocksPlatform::importGPC($_REQUEST['template_subject'],'string','');
  375. @$content = DevblocksPlatform::importGPC($_REQUEST['template_content'],'string','');
  376. @$delete = DevblocksPlatform::importGPC($_REQUEST['do_delete'],'integer',0);
  377. $worker = CerberusApplication::getActiveWorker();
  378. if(empty($delete)) {
  379. $fields = array(
  380. DAO_Watcher2Template::TITLE => $title,
  381. DAO_Watcher2Template::DESCRIPTION => $description,
  382. DAO_Watcher2Template::TEMPLATE_TYPE => $type,
  383. DAO_Watcher2Template::TEMPLATE_SUBJECT => $subject,
  384. DAO_Watcher2Template::TEMPLATE_CONTENT => $content,
  385. DAO_Watcher2Template::OWNER_ID => $worker->id,
  386. );
  387. if(empty($id)) { // new
  388. $id = DAO_Watcher2Template::create($fields);
  389. } else { // edit
  390. DAO_Watcher2Template::update($id, $fields);
  391. }
  392. } else { // delete
  393. DAO_Watcher2Template::delete($id);
  394. }
  395. }
  396. // Ajax
  397. function getTemplateAction() {
  398. @$id = DevblocksPlatform::importGPC($_REQUEST['id'],'integer');
  399. @$reply_id = DevblocksPlatform::importGPC($_REQUEST['reply_id'],'integer');
  400. $template = DAO_Watcher2Template::get($id);
  401. echo $template->getRenderedContent($reply_id);
  402. }
  403. // Ajax
  404. function getTemplatesAction() {
  405. @$txt_name = DevblocksPlatform::importGPC($_REQUEST['txt_name'],'string','');
  406. @$reply_id = DevblocksPlatform::importGPC($_REQUEST['reply_id'],'integer');
  407. @$type = DevblocksPlatform::importGPC($_REQUEST['type'],'integer',0);
  408. $db = DevblocksPlatform::getDatabaseService();
  409. $tpl = DevblocksPlatform::getTemplateService();
  410. $tpl->assign('path', $this->_TPL_PATH);
  411. $tpl->assign('reply_id', $reply_id);
  412. $tpl->assign('txt_name', $txt_name);
  413. $where = sprintf("%s = %d",
  414. DAO_Watcher2Template::TEMPLATE_TYPE,
  415. $type
  416. );
  417. $templates = DAO_Watcher2Template::getWhere($where);
  418. $tpl->assign('templates', $templates);
  419. $tpl->display('file:' . $this->_TPL_PATH . 'watcher2_template/template_results.tpl');
  420. }
  421. };
  422. class C4_Watcher2View extends C4_AbstractView {
  423. const DEFAULT_ID = 'watchers2';
  424. function __construct() {
  425. $this->id = self::DEFAULT_ID;
  426. $this->name = 'Watchers 2.0';
  427. $this->renderLimit = 25;
  428. $this->renderSortBy = SearchFields_Watcher2MailFilter::ID;
  429. $this->renderSortAsc = true;
  430. $this->view_columns = array(
  431. SearchFields_Watcher2MailFilter::CREATED,
  432. SearchFields_Watcher2MailFilter::WORKER_ID,
  433. SearchFields_Watcher2MailFilter::POS,
  434. );
  435. $this->doResetCriteria();
  436. }
  437. function getData() {
  438. $objects = DAO_Watcher2MailFilter::search(
  439. array(),
  440. $this->params,
  441. $this->renderLimit,
  442. $this->renderPage,
  443. $this->renderSortBy,
  444. $this->renderSortAsc
  445. );
  446. return $objects;
  447. }
  448. function render() {
  449. $this->_sanitize();
  450. $tpl = DevblocksPlatform::getTemplateService();
  451. $tpl->assign('id', $this->id);
  452. $tpl->assign('view', $this);
  453. // Workers
  454. $workers = DAO_Worker::getAll();
  455. $tpl->assign('workers', $workers);
  456. $tpl->cache_lifetime = "0";
  457. $tpl->assign('view_fields', $this->getColumns());
  458. $tpl->display('file:' . DEVBLOCKS_PLUGIN_PATH . 'cerb5blog.watchers2/templates/config/watchers2/view.tpl');
  459. }
  460. function renderCriteria($field) {
  461. $tpl = DevblocksPlatform::getTemplateService();
  462. $tpl->assign('id', $this->id);
  463. switch($field) {
  464. case SearchFields_Watcher2MailFilter::NAME:
  465. $tpl->display('file:' . DEVBLOCKS_PLUGIN_PATH . 'cerberusweb.core/templates/internal/views/criteria/__string.tpl');
  466. break;
  467. case SearchFields_Watcher2MailFilter::ID:
  468. case SearchFields_Watcher2MailFilter::POS:
  469. $tpl->display('file:' . DEVBLOCKS_PLUGIN_PATH . 'cerberusweb.core/templates/internal/views/criteria/__number.tpl');
  470. break;
  471. case SearchFields_Watcher2MailFilter::CREATED:
  472. $tpl->display('file:' . DEVBLOCKS_PLUGIN_PATH . 'cerberusweb.core/templates/internal/views/criteria/__date.tpl');
  473. break;
  474. case SearchFields_Watcher2MailFilter::IS_DISABLED:
  475. $tpl->display('file:' . DEVBLOCKS_PLUGIN_PATH . 'cerberusweb.core/templates/internal/views/criteria/__bool.tpl');
  476. break;
  477. case SearchFields_Watcher2MailFilter::WORKER_ID:
  478. $workers = DAO_Worker::getAll();
  479. $tpl->assign('workers', $workers);
  480. $tpl->display('file:' . DEVBLOCKS_PLUGIN_PATH . 'cerberusweb.core/templates/internal/views/criteria/__worker.tpl');
  481. break;
  482. default:
  483. echo '';
  484. break;
  485. }
  486. }
  487. function renderCriteriaParam($param) {
  488. $field = $param->field;
  489. $values = !is_array($param->value) ? array($param->value) : $param->value;
  490. switch($field) {
  491. case SearchFields_Watcher2MailFilter::WORKER_ID:
  492. $workers = DAO_Worker::getAll();
  493. $strings = array();
  494. foreach($values as $val) {
  495. if(0==$val) {
  496. $strings[] = "Nobody";
  497. } else {
  498. if(!isset($workers[$val]))
  499. continue;
  500. $strings[] = $workers[$val]->getName();
  501. }
  502. }
  503. echo implode(", ", $strings);
  504. break;
  505. default:
  506. parent::renderCriteriaParam($param);
  507. break;
  508. }
  509. }
  510. static function getFields() {
  511. return SearchFields_Watcher2MailFilter::getFields();
  512. }
  513. static function getSearchFields() {
  514. $fields = self::getFields();
  515. unset($fields[SearchFields_Watcher2MailFilter::ID]);
  516. return $fields;
  517. }
  518. static function getColumns() {
  519. $fields = self::getFields();
  520. unset($fields[SearchFields_Watcher2MailFilter::ID]);
  521. return $fields;
  522. }
  523. function doResetCriteria() {
  524. parent::doResetCriteria();
  525. $this->params = array(
  526. // SearchFields_Watcher2MailFilter::LOG_DATE => new DevblocksSearchCriteria(SearchFields_Watcher2MailFilter::LOG_DATE,DevblocksSearchCriteria::OPER_BETWEEN,array('-1 month','now')),
  527. );
  528. }
  529. function doSetCriteria($field, $oper, $value) {
  530. $criteria = null;
  531. switch($field) {
  532. case SearchFields_Watcher2MailFilter::NAME:
  533. // force wildcards if none used on a LIKE
  534. if(($oper == DevblocksSearchCriteria::OPER_LIKE || $oper == DevblocksSearchCriteria::OPER_NOT_LIKE)
  535. && false === (strpos($value,'*'))) {
  536. $value = '*'.$value.'*';
  537. }
  538. $criteria = new DevblocksSearchCriteria($field, $oper, $value);
  539. break;
  540. case SearchFields_Watcher2MailFilter::ID:
  541. case SearchFields_Watcher2MailFilter::POS:
  542. $criteria = new DevblocksSearchCriteria($field,$oper,$value);
  543. break;
  544. case SearchFields_Watcher2MailFilter::WORKER_ID:
  545. @$worker_id = DevblocksPlatform::importGPC($_REQUEST['worker_id'],'array',array());
  546. $criteria = new DevblocksSearchCriteria($field,$oper,$worker_id);
  547. break;
  548. case SearchFields_Watcher2MailFilter::IS_DISABLED:
  549. @$bool = DevblocksPlatform::importGPC($_REQUEST['bool'],'integer',1);
  550. $criteria = new DevblocksSearchCriteria($field,$oper,$bool);
  551. break;
  552. case SearchFields_Watcher2MailFilter::CREATED:
  553. @$from = DevblocksPlatform::importGPC($_REQUEST['from'],'string','');
  554. @$to = DevblocksPlatform::importGPC($_REQUEST['to'],'string','');
  555. if(empty($from)) $from = 0;
  556. if(empty($to)) $to = 'today';
  557. $criteria = new DevblocksSearchCriteria($field,$oper,array($from,$to));
  558. break;
  559. }
  560. if(!empty($criteria)) {
  561. $this->params[$field] = $criteria;
  562. $this->renderPage = 0;
  563. }
  564. }
  565. function doBulkUpdate($filter, $do, $ids=array()) {
  566. @set_time_limit(0);
  567. $change_fields = array();
  568. $custom_fields = array();
  569. $do_delete = false;
  570. // Make sure we have actions
  571. if(empty($do))
  572. return;
  573. // Make sure we have checked items if we want a checked list
  574. if(0 == strcasecmp($filter,"checks") && empty($ids))
  575. return;
  576. if(is_array($do))
  577. foreach($do as $k => $v) {
  578. switch($k) {
  579. case 'status':
  580. if(2==$v) {
  581. $do_delete = true;
  582. } else {
  583. $change_fields[DAO_Watcher2MailFilter::IS_DISABLED] = (!empty($v)?1:0);
  584. }
  585. break;
  586. default:
  587. // Custom fields
  588. // if(substr($k,0,3)=="cf_") {
  589. // $custom_fields[substr($k,3)] = $v;
  590. // }
  591. break;
  592. }
  593. }
  594. $pg = 0;
  595. if(empty($ids))
  596. do {
  597. list($objects,$null) = DAO_Watcher2MailFilter::search(
  598. array(),
  599. $this->params,
  600. 100,
  601. $pg++,
  602. SearchFields_Watcher2MailFilter::ID,
  603. true,
  604. false
  605. );
  606. $ids = array_merge($ids, array_keys($objects));
  607. } while(!empty($objects));
  608. $batch_total = count($ids);
  609. for($x=0;$x<=$batch_total;$x+=100) {
  610. $batch_ids = array_slice($ids,$x,100);
  611. if($do_delete) {
  612. DAO_Watcher2MailFilter::delete($batch_ids);
  613. } else {
  614. DAO_Watcher2MailFilter::update($batch_ids, $change_fields);
  615. // Custom Fields
  616. //self::_doBulkSetCustomFields(ChCustomFieldSource_TimeEntry::ID, $custom_fields, $batch_ids);
  617. }
  618. unset($batch_ids);
  619. }
  620. unset($ids);
  621. }
  622. };
  623. class DAO_Watcher2MailFilter extends DevblocksORMHelper {
  624. const ID = 'id';
  625. const POS = 'pos';
  626. const NAME = 'name';
  627. const CREATED = 'created';
  628. const IS_DISABLED = 'is_disabled';
  629. const WORKER_ID = 'worker_id';
  630. const CRITERIA_SER = 'criteria_ser';
  631. const ACTIONS_SER = 'actions_ser';
  632. static function create($fields) {
  633. $db = DevblocksPlatform::getDatabaseService();
  634. $id = $db->GenID('generic_seq');
  635. $sql = sprintf("INSERT INTO cerb5blog_watchers2_filter (id,created) ".
  636. "VALUES (%d,%d)",
  637. $id,
  638. time()
  639. );
  640. $db->Execute($sql);
  641. self::update($id, $fields);
  642. return $id;
  643. }
  644. static function update($ids, $fields) {
  645. parent::_update($ids, 'cerb5blog_watchers2_filter', $fields);
  646. }
  647. /**
  648. * @param string $where
  649. * @return Model_Watcher2MailFilter[]
  650. */
  651. static function getWhere($where=null) {
  652. $db = DevblocksPlatform::getDatabaseService();
  653. $sql = "SELECT id, pos, name, created, is_disabled, worker_id, criteria_ser, actions_ser ".
  654. "FROM cerb5blog_watchers2_filter ".
  655. (!empty($where) ? sprintf("WHERE %s ",$where) : "").
  656. "ORDER BY pos DESC";
  657. $rs = $db->Execute($sql);
  658. return self::_getObjectsFromResult($rs);
  659. }
  660. /**
  661. * @param integer $id
  662. * @return Model_Watcher2MailFilter */
  663. static function get($id) {
  664. $objects = self::getWhere(sprintf("%s = %d",
  665. self::ID,
  666. $id
  667. ));
  668. if(isset($objects[$id]))
  669. return $objects[$id];
  670. return null;
  671. }
  672. /**
  673. * @param ADORecordSet $rs
  674. * @return Model_Watcher2MailFilter[]
  675. */
  676. static private function _getObjectsFromResult($rs) {
  677. $objects = array();
  678. while(!$rs->EOF) {
  679. $object = new Model_Watcher2MailFilter();
  680. $object->id = $rs->fields['id'];
  681. $object->pos = $rs->fields['pos'];
  682. $object->name = $rs->fields['name'];
  683. $object->created = $rs->fields['created'];
  684. $object->is_disabled = intval($rs->fields['is_disabled']);
  685. $object->worker_id = intval($rs->fields['worker_id']);
  686. if(null != (@$criteria_ser = $rs->fields['criteria_ser']))
  687. if(false === (@$object->criteria = unserialize($criteria_ser)))
  688. $object->criteria = array();
  689. if(null != (@$actions_ser = $rs->fields['actions_ser']))
  690. if(false === ($object->actions = unserialize($actions_ser)))
  691. $object->actions = array();
  692. $objects[$object->id] = $object;
  693. $rs->MoveNext();
  694. }
  695. return $objects;
  696. }
  697. public static function increment($id) {
  698. $db = DevblocksPlatform::getDatabaseService();
  699. $db->Execute(sprintf("UPDATE cerb5blog_watchers2_filter SET pos = pos + 1 WHERE id = %d",
  700. $id
  701. ));
  702. }
  703. static function delete($ids) {
  704. if(!is_array($ids)) $ids = array($ids);
  705. $db = DevblocksPlatform::getDatabaseService();
  706. if(empty($ids))
  707. return;
  708. $ids_list = implode(',', $ids);
  709. $db->Execute(sprintf("DELETE FROM cerb5blog_watchers2_filter WHERE id IN (%s)", $ids_list));
  710. return true;
  711. }
  712. private static function _deleteWhere($where) {
  713. if(empty($where))
  714. return FALSE;
  715. $db = DevblocksPlatform::getDatabaseService();
  716. $sql = sprintf("DELETE FROM cerb5blog_watchers2_filter WHERE %s", $where);
  717. $db->Execute($sql);
  718. }
  719. public static function deleteByWorkerIds($ids) {
  720. if(!is_array($ids)) $ids = array($ids);
  721. self::_deleteWhere(sprintf("%s IN (%s)",
  722. self::WORKER_ID,
  723. implode(',', $ids)
  724. ));
  725. }
  726. public static function deleteByGroupIds($ids) {
  727. if(!is_array($ids)) $ids = array($ids);
  728. // [TODO] use cache
  729. $filters = self::getWhere();
  730. foreach($filters as $filter_id => $filter) {
  731. if(!isset($filter->criteria['groups']))
  732. continue;
  733. // If we're using the group being nuked...
  734. $changed = false;
  735. foreach($ids as $group_id) {
  736. if(isset($filter->criteria['groups']['groups'][$group_id])) {
  737. unset($filter->criteria['groups']['groups'][$group_id]);
  738. $changed = true;
  739. }
  740. }
  741. // If we changed the criteria of a filter, save it
  742. if($changed) {
  743. $fields = array(
  744. DAO_Watcher2MailFilter::CRITERIA_SER => serialize($filter->criteria),
  745. );
  746. DAO_Watcher2MailFilter::update($filter->id, $fields);
  747. }
  748. }
  749. // [TODO] invalidate cache
  750. }
  751. public static function deleteByBucketIds($ids) {
  752. if(!is_array($ids)) $ids = array($ids);
  753. // [TODO] use cache
  754. $filters = self::getWhere();
  755. foreach($filters as $filter_id => $filter) {
  756. if(!isset($filter->criteria['groups']['groups']))
  757. continue;
  758. // If we're using the bucket being nuked...
  759. $changed = false;
  760. foreach($filter->criteria['groups']['groups'] as $group_id => $buckets) {
  761. foreach($ids as $bucket_id) {
  762. if(false !== ($pos = array_search($bucket_id, $buckets))) {
  763. unset($filter->criteria['groups']['groups'][$group_id][$pos]);
  764. $changed = true;
  765. }
  766. }
  767. }
  768. if($changed) {
  769. $fields = array(
  770. DAO_Watcher2MailFilter::CRITERIA_SER => serialize($filter->criteria),
  771. );
  772. DAO_Watcher2MailFilter::update($filter->id, $fields);
  773. }
  774. }
  775. // [TODO] invalidate cache
  776. }
  777. /**
  778. * Enter description here...
  779. *
  780. * @param DevblocksSearchCriteria[] $params
  781. * @param integer $limit
  782. * @param integer $page
  783. * @param string $sortBy
  784. * @param boolean $sortAsc
  785. * @param boolean $withCounts
  786. * @return array
  787. */
  788. static function search($columns, $params, $limit=10, $page=0, $sortBy=null, $sortAsc=null, $withCounts=true) {
  789. $db = DevblocksPlatform::getDatabaseService();
  790. $fields = SearchFields_Watcher2MailFilter::getFields();
  791. // Sanitize
  792. if(!isset($fields[$sortBy]))
  793. $sortBy=null;
  794. list($tables,$wheres) = parent::_parseSearchParams($params, $columns, $fields,$sortBy);
  795. $start = ($page * $limit); // [JAS]: 1-based [TODO] clean up + document
  796. $select_sql = sprintf("SELECT ".
  797. "cwf.id as %s, ".
  798. "cwf.pos as %s, ".
  799. "cwf.name as %s, ".
  800. "cwf.created as %s, ".
  801. "cwf.is_disabled as %s, ".
  802. "cwf.worker_id as %s ",
  803. SearchFields_Watcher2MailFilter::ID,
  804. SearchFields_Watcher2MailFilter::POS,
  805. SearchFields_Watcher2MailFilter::NAME,
  806. SearchFields_Watcher2MailFilter::CREATED,
  807. SearchFields_Watcher2MailFilter::IS_DISABLED,
  808. SearchFields_Watcher2MailFilter::WORKER_ID
  809. );
  810. $join_sql =
  811. "FROM cerb5blog_watchers2_filter cwf "
  812. ;
  813. // [JAS]: Dynamic table joins
  814. // (isset($tables['o']) ? "LEFT JOIN contact_org o ON (o.id=tt.debit_org_id)" : " ").
  815. // (isset($tables['mc']) ? "INNER JOIN message_content mc ON (mc.message_id=m.id)" : " ").
  816. // Custom field joins
  817. // list($select_sql, $join_sql, $has_multiple_values) = self::_appendSelectJoinSqlForCustomFieldTables(
  818. // $tables,
  819. // $params,
  820. // 'cwf.id',
  821. // $select_sql,
  822. // $join_sql
  823. // );
  824. $where_sql = "".
  825. (!empty($wheres) ? sprintf("WHERE %s ",implode(' AND ',$wheres)) : "");
  826. $sort_sql = (!empty($sortBy) ? sprintf("ORDER BY %s %s ",$sortBy,($sortAsc || is_null($sortAsc))?"ASC":"DESC") : " ");
  827. $sql =
  828. $select_sql.
  829. $join_sql.
  830. $where_sql.
  831. //($has_multiple_values ? 'GROUP BY cwf.id ' : '').
  832. $sort_sql;
  833. $rs = $db->SelectLimit($sql,$limit,$start) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
  834. $results = array();
  835. if(is_a($rs,'ADORecordSet'))
  836. while(!$rs->EOF) {
  837. foreach($rs->fields as $f => $v) {
  838. $result[$f] = $v;
  839. }
  840. $id = intval($rs->fields[SearchFields_Watcher2MailFilter::ID]);
  841. $results[$id] = $result;
  842. $rs->MoveNext();
  843. }
  844. // [JAS]: Count all
  845. $total = -1;
  846. if($withCounts) {
  847. $count_sql =
  848. ($has_multiple_values ? "SELECT COUNT(DISTINCT cwf.id) " : "SELECT COUNT(cwf.id) ").
  849. $join_sql.
  850. $where_sql;
  851. $total = $db->GetOne($count_sql);
  852. }
  853. return array($results,$total);
  854. }
  855. };
  856. class SearchFields_Watcher2MailFilter {
  857. // Watcher2_Mail_Filter
  858. const ID = 'cwf_id';
  859. const POS = 'cwf_pos';
  860. const NAME = 'cwf_name';
  861. const CREATED = 'cwf_created';
  862. const WORKER_ID = 'cwf_worker_id';
  863. const IS_DISABLED = 'cwf_is_disabled';
  864. /**
  865. * @return DevblocksSearchField[]
  866. */
  867. static function getFields() {
  868. $translate = DevblocksPlatform::getTranslationService();
  869. $columns = array(
  870. self::ID => new DevblocksSearchField(self::ID, 'cwf', 'id', null, ucwords($translate->_('common.id'))),
  871. self::POS => new DevblocksSearchField(self::POS, 'cwf', 'pos', null, ucwords($translate->_('watcher2.filter.model.hits'))),
  872. self::NAME => new DevblocksSearchField(self::NAME, 'cwf', 'name', null, ucwords($translate->_('common.name'))),
  873. self::CREATED => new DevblocksSearchField(self::CREATED, 'cwf', 'created', null, ucwords($translate->_('common.created'))),
  874. self::WORKER_ID => new DevblocksSearchField(self::WORKER_ID, 'cwf', 'worker_id', null, ucwords($translate->_('common.worker'))),
  875. self::IS_DISABLED => new DevblocksSearchField(self::IS_DISABLED, 'cwf', 'is_disabled', null, ucwords($translate->_('common.disabled'))),
  876. );
  877. // Custom Fields
  878. // $fields = DAO_CustomField::getBySource(ChCustomFieldSource_TimeEntry::ID);
  879. // if(is_array($fields))
  880. // foreach($fields as $field_id => $field) {
  881. // $key = 'cf_'.$field_id;
  882. // $columns[$key] = new DevblocksSearchField($key,$key,'field_value',null,$field->name);
  883. // }
  884. // Sort by label (translation-conscious)
  885. uasort($columns, create_function('$a, $b', "return strcasecmp(\$a->db_label,\$b->db_label);\n"));
  886. return $columns;
  887. }
  888. };
  889. class Model_Watcher2MailFilter {
  890. public $id;
  891. public $pos;
  892. public $name;
  893. public $created;
  894. public $is_disabled=0;
  895. public $worker_id;
  896. public $criteria;
  897. public $actions;
  898. /**
  899. * @return Model_Watcher2MailFilter[]|false
  900. */
  901. static function getMatches(CerberusTicket $ticket, $event, $only_worker_id=null) {
  902. $matches = array();
  903. if(!empty($only_worker_id)) {
  904. $filters = DAO_Watcher2MailFilter::getWhere(sprintf("%s = %d AND %s = %d",
  905. DAO_Watcher2MailFilter::WORKER_ID,
  906. $only_worker_id,
  907. DAO_Watcher2MailFilter::IS_DISABLED,
  908. 0
  909. ));
  910. } else {
  911. $filters = DAO_Watcher2MailFilter::getWhere(sprintf("%s = %d",
  912. DAO_Watcher2MailFilter::IS_DISABLED,
  913. 0
  914. ));
  915. }
  916. // [JAS]: Don't send obvious spam to watchers2.
  917. if($ticket->spam_score >= 0.9000)
  918. return false;
  919. // Build our objects
  920. $ticket_from = DAO_Address::get($ticket->last_wrote_address_id);
  921. $ticket_group_id = $ticket->team_id;
  922. // [TODO] These expensive checks should only populate when needed
  923. $messages = DAO_Ticket::getMessagesByTicket($ticket->id);
  924. $message_headers = array();
  925. if(empty($messages))
  926. return false;
  927. if(null != (@$message_last = array_pop($messages))) { /* @var $message_last CerberusMessage */
  928. $message_headers = $message_last->getHeaders();
  929. }
  930. // Clear the rest of the message manifests
  931. unset($messages);
  932. $custom_fields = DAO_CustomField::getAll();
  933. // Lazy load when needed on criteria basis
  934. $ticket_field_values = null;
  935. $address_field_values = null;
  936. $org_field_values = null;
  937. // Worker memberships (for checking permissions)
  938. $workers = DAO_Worker::getAll();
  939. $group_rosters = DAO_Group::getRosters();
  940. // Check filters
  941. if(is_array($filters))
  942. foreach($filters as $filter) { /* @var $filter Model_Watcher2MailFilter */
  943. $passed = 0;
  944. // check the worker's group memberships
  945. if(!isset($workers[$filter->worker_id]) // worker doesn't exist
  946. || $workers[$filter->worker_id]->is_disabled // is disabled
  947. || (!$workers[$filter->worker_id]->is_superuser // not a superuser, and...
  948. && !isset($group_rosters[$ticket->team_id][$filter->worker_id]))) { // no membership
  949. continue;
  950. }
  951. // check criteria
  952. foreach($filter->criteria as $rule_key => $rule) {
  953. @$value = $rule['value'];
  954. switch($rule_key) {
  955. case 'dayofweek':
  956. $current_day = strftime('%w');
  957. //$current_day = 1;
  958. // Forced to English abbrevs as indexes Full names are translated well being displayed
  959. $days = array('sun','mon','tue','wed','thu','fri','sat');
  960. // Is the current day enabled?
  961. if(isset($rule[$days[$current_day]])) {
  962. $passed++;
  963. }
  964. break;
  965. case 'timeofday':
  966. $current_hour = strftime('%H');
  967. $current_min = strftime('%M');
  968. //$current_hour = 17;
  969. //$current_min = 5;
  970. if(null != ($from_time = @$rule['from']))
  971. list($from_hour, $from_min) = explode(':', $from_time);
  972. if(null != ($to_time = @$rule['to']))
  973. if(list($to_hour, $to_min) = explode(':', $to_time));
  974. // Do we need to wrap around to the next day's hours?
  975. if($from_hour > $to_hour) { // yes
  976. $to_hour += 24; // add 24 hrs to the destination (1am = 25th hour)
  977. }
  978. // Are we in the right 24 hourly range?
  979. if((integer)$current_hour >= $from_hour && (integer)$current_hour <= $to_hour) {
  980. // If we're in the first hour, are we minutes early?
  981. if($current_hour==$from_hour && (integer)$current_min < $from_min)
  982. break;
  983. // If we're in the last hour, are we minutes late?
  984. if($current_hour==$to_hour && (integer)$current_min > $to_min)
  985. break;
  986. $passed++;
  987. }
  988. break;
  989. case 'event':
  990. if(!empty($event) && is_array($rule) && isset($rule[$event]))
  991. $passed++;
  992. break;
  993. case 'groups':
  994. if(null !== (@$group_buckets = $rule['groups'][$ticket->team_id]) // group is set
  995. && (empty($group_buckets) || in_array($ticket->category_id,$group_buckets)))
  996. $passed++;
  997. break;
  998. case 'next_worker_id':
  999. // If it's an assigned event, we only care about the filter's owner
  1000. if(!empty($event) && 0==strcasecmp($event,'ticket_assignment')) {
  1001. if(intval($value)==intval($filter->worker_id)) {
  1002. $passed++;
  1003. break;
  1004. }
  1005. }
  1006. if(intval($value)==intval($ticket->next_worker_id))
  1007. $passed++;
  1008. break;
  1009. case 'mask':
  1010. $regexp_mask = DevblocksPlatform::strToRegExp($value);
  1011. if(@preg_match($regexp_mask, $ticket->mask)) {
  1012. $passed++;
  1013. }
  1014. break;
  1015. case 'from':
  1016. $regexp_from = DevblocksPlatform::strToRegExp($value);
  1017. if(@preg_match($regexp_from, $ticket_from->email)) {
  1018. $passed++;
  1019. }
  1020. break;
  1021. case 'subject':
  1022. $regexp_subject = DevblocksPlatform::strToRegExp($value);
  1023. if(@preg_match($regexp_subject, $ticket->subject)) {
  1024. $passed++;
  1025. }
  1026. break;
  1027. case 'body':
  1028. if(null == ($message_body = $message_last->getContent()))
  1029. break;
  1030. // Line-by-line body scanning (sed-like)
  1031. $lines = preg_split("/[\r\n]/", $message_body);
  1032. if(is_array($lines))
  1033. foreach($lines as $line) {
  1034. if(@preg_match($value, $line)) {
  1035. $passed++;
  1036. break;
  1037. }
  1038. }
  1039. break;
  1040. case 'header1':
  1041. case 'header2':
  1042. case 'header3':
  1043. case 'header4':
  1044. case 'header5':
  1045. @$header = strtolower($rule['header']);
  1046. if(empty($header)) {
  1047. $passed++;
  1048. break;
  1049. }
  1050. if(empty($value)) { // we're checking for null/blanks
  1051. if(!isset($message_headers[$header]) || empty($message_headers[$header])) {
  1052. $passed++;
  1053. }
  1054. } elseif(isset($message_headers[$header]) && !empty($message_headers[$header])) {
  1055. $regexp_header = DevblocksPlatform::strToRegExp($value);
  1056. // Flatten CRLF
  1057. if(@preg_match($regexp_header, str_replace(array("\r","\n"),' ',$message_headers[$header]))) {
  1058. $passed++;
  1059. }
  1060. }
  1061. break;
  1062. default: // ignore invalids
  1063. // Custom Fields
  1064. if(0==strcasecmp('cf_',substr($rule_key,0,3))) {
  1065. $field_id = substr($rule_key,3);
  1066. // Make sure it exists
  1067. if(null == (@$field = $custom_fields[$field_id]))
  1068. continue;
  1069. // Lazy values loader
  1070. $field_values = array();
  1071. switch($field->source_extension) {
  1072. case ChCustomFieldSource_Address::ID:
  1073. if(null == $address_field_values)
  1074. $address_field_values = array_shift(DAO_CustomFieldValue::getValuesBySourceIds(ChCustomFieldSource_Address::ID, $ticket_from->id));
  1075. $field_values =& $address_field_values;
  1076. break;
  1077. case ChCustomFieldSource_Org::ID:
  1078. if(null == $org_field_values)
  1079. $org_field_values = array_shift(DAO_CustomFieldValue::getValuesBySourceIds(ChCustomFieldSource_Org::ID, $ticket_from->contact_org_id));
  1080. $field_values =& $org_field_values;
  1081. break;
  1082. case ChCustomFieldSource_Ticket::ID:
  1083. if(null == $ticket_field_values)
  1084. $ticket_field_values = array_shift(DAO_CustomFieldValue::getValuesBySourceIds(ChCustomFieldSource_Ticket::ID, $ticket->id));
  1085. $field_values =& $ticket_field_values;
  1086. break;
  1087. }
  1088. // Type sensitive value comparisons
  1089. // [TODO] Operators
  1090. switch($field->type) {
  1091. case 'S': // string
  1092. case 'T': // clob
  1093. case 'U': // URL
  1094. $field_val = isset($field_values[$field_id]) ? $field_values[$field_id] : '';
  1095. $oper = isset($rule['oper']) ? $rule['oper'] : "=";
  1096. if($oper == "=" && @preg_match(DevblocksPlatform::strToRegExp($value, true), $field_val))
  1097. $passed++;
  1098. elseif($oper == "!=" && @!preg_match(DevblocksPlatform::strToRegExp($value, true), $field_val))
  1099. $passed++;
  1100. break;
  1101. case 'N': // number
  1102. $field_val = isset($field_values[$field_id]) ? $field_values[$field_id] : 0;
  1103. $oper = isset($rule['oper']) ? $rule['oper'] : "=";
  1104. if($oper=="=" && intval($field_val)==intval($value))
  1105. $passed++;
  1106. elseif($oper=="!=" && intval($field_val)!=intval($value))
  1107. $passed++;
  1108. elseif($oper==">" && intval($field_val) > intval($value))
  1109. $passed++;
  1110. elseif($oper=="<" && intval($field_val) < intval($value))
  1111. $passed++;
  1112. break;
  1113. case 'E': // date
  1114. $field_val = isset($field_values[$field_id]) ? intval($field_values[$field_id]) : 0;
  1115. $from = isset($rule['from']) ? $rule['from'] : "0";
  1116. $to = isset($rule['to']) ? $rule['to'] : "now";
  1117. if(intval(@strtotime($from)) <= $field_val && intval(@strtotime($to)) >= $field_val) {
  1118. $passed++;
  1119. }
  1120. break;
  1121. case 'C': // checkbox
  1122. $field_val = isset($field_values[$field_id]) ? $field_values[$field_id] : 0;
  1123. if(intval($value)==intval($field_val))
  1124. $passed++;
  1125. break;
  1126. case 'D': // dropdown
  1127. case 'X': // multi-checkbox
  1128. case 'M': // multi-picklist
  1129. case 'W': // worker
  1130. $field_val = isset($field_values[$field_id]) ? $field_values[$field_id] : array();
  1131. if(!is_array($value)) $value = array($value);
  1132. if(is_array($field_val)) { // if multiple things set
  1133. foreach($field_val as $v) { // loop through possible
  1134. if(isset($value[$v])) { // is any possible set?
  1135. $passed++;
  1136. break;
  1137. }
  1138. }
  1139. } else { // single
  1140. if(isset($value[$field_val])) { // is our set field in possibles?
  1141. $passed++;
  1142. break;
  1143. }
  1144. }
  1145. break;
  1146. }
  1147. }
  1148. break;
  1149. }
  1150. }
  1151. // If our rule matched every criteria, stop and return the filter
  1152. if($passed == count($filter->criteria)) {
  1153. DAO_Watcher2MailFilter::increment($filter->id); // ++ the times we've matched
  1154. $matches[$filter->id] = $filter;
  1155. }
  1156. }
  1157. if(!empty($matches))
  1158. return $matches;
  1159. // No matches
  1160. return false;
  1161. }
  1162. };
  1163. class DAO_Watcher2Template extends DevblocksORMHelper {
  1164. const _TABLE = 'cerb5blog_watchers2_template';
  1165. const ID = 'id';
  1166. const TITLE = 'title';
  1167. const DESCRIPTION = 'description';
  1168. const TEMPLATE_TYPE = 'template_type';
  1169. const TEMPLATE_SUBJECT = 'template_subject';
  1170. const TEMPLATE_CONTENT = 'template_content';
  1171. const OWNER_ID = 'owner_id';
  1172. public static function create($fields) {
  1173. $db = DevblocksPlatform::getDatabaseService();
  1174. $id = $db->GenID('generic_seq');
  1175. $sql = sprintf("INSERT INTO %s (id,title,description,template_type,template_subject,template_content,owner_id) ".
  1176. "VALUES (%d,'','',0,'','',0)",
  1177. self::_TABLE,
  1178. $id
  1179. );
  1180. $rs = $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
  1181. self::update($id, $fields);
  1182. return $id;
  1183. }
  1184. public static function update($ids, $fields) {
  1185. // [TODO] Overload CONTENT as BlobUpdate
  1186. parent::_update($ids, self::_TABLE, $fields);
  1187. }
  1188. public static function delete($ids) {
  1189. if(!is_array($ids)) $ids = array($ids);
  1190. $db = DevblocksPlatform::getDatabaseService();
  1191. if(empty($ids))
  1192. return;
  1193. $sql = sprintf("DELETE QUICK FROM %s WHERE id IN (%s)",
  1194. self::_TABLE,
  1195. implode(',', $ids)
  1196. );
  1197. $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
  1198. }
  1199. public function getByType($type) {
  1200. return self::getWhere(sprintf("%s = %d",
  1201. self::TEMPLATE_TYPE,
  1202. $type
  1203. ));
  1204. }
  1205. /**
  1206. * Enter description here...
  1207. *
  1208. * @param string $where
  1209. * @return Model_MailTemplate[]
  1210. */
  1211. public function getWhere($where=null) {
  1212. $db = DevblocksPlatform::getDatabaseService();
  1213. $sql = sprintf("SELECT id,title,description,template_type,template_subject,template_content,owner_id ".
  1214. "FROM %s ".
  1215. (!empty($where) ? ("WHERE $where ") : " ").
  1216. " ORDER BY title ",
  1217. self::_TABLE
  1218. );
  1219. $rs = $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
  1220. return self::_createObjectsFromResultSet($rs);
  1221. }
  1222. /**
  1223. * Enter description here...
  1224. *
  1225. * @param integer $id
  1226. * @return Model_MailTemplate
  1227. */
  1228. public static function get($id) {
  1229. $objects = self::getWhere(sprintf("id = %d", $id));
  1230. if(isset($objects[$id]))
  1231. return $objects[$id];
  1232. return null;
  1233. }
  1234. public static function _createObjectsFromResultSet(ADORecordSet $rs) {
  1235. $objects = array();
  1236. if(is_a($rs,'ADORecordSet'))
  1237. while(!$rs->EOF) {
  1238. $object = new Model_MailTemplate();
  1239. $object->id = intval($rs->fields['id']);
  1240. $object->title = $rs->fields['title'];
  1241. $object->description = $rs->fields['description'];
  1242. $object->template_type = intval($rs->fields['template_type']);
  1243. $object->template_subject = $rs->fields['template_subject'];
  1244. $object->template_content = $rs->fields['template_content'];
  1245. $object->owner_id = intval($rs->fields['owner_id']);
  1246. $objects[$object->id] = $object;
  1247. $rs->MoveNext();
  1248. }
  1249. return $objects;
  1250. }
  1251. };