/api/DAO.class.php
PHP | 7276 lines | 5017 code | 1388 blank | 871 comment | 454 complexity | b4be966c677f6ad2bfba842536469640 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- <?php
- /***********************************************************************
- | Cerberus Helpdesk(tm) developed by WebGroup Media, LLC.
- |-----------------------------------------------------------------------
- | All source code & content (c) Copyright 2007, WebGroup Media LLC
- | unless specifically noted otherwise.
- |
- | This source code is released under the Cerberus Public License.
- | The latest version of this license can be found here:
- | http://www.cerberusweb.com/license.php
- |
- | By using this software, you acknowledge having read this license
- | and agree to be bound thereby.
- | ______________________________________________________________________
- | http://www.cerberusweb.com http://www.webgroupmedia.com/
- ***********************************************************************/
- /*
- * IMPORTANT LICENSING NOTE from your friends on the Cerberus Helpdesk Team
- *
- * Sure, it would be so easy to just cheat and edit this file to use the
- * software without paying for it. But we trust you anyway. In fact, we're
- * writing this software for you!
- *
- * Quality software backed by a dedicated team takes money to develop. We
- * don't want to be out of the office bagging groceries when you call up
- * needing a helping hand. We'd rather spend our free time coding your
- * feature requests than mowing the neighbors' lawns for rent money.
- *
- * We've never believed in encoding our source code out of paranoia over not
- * getting paid. We want you to have the full source code and be able to
- * make the tweaks your organization requires to get more done -- despite
- * having less of everything than you might need (time, people, money,
- * energy). We shouldn't be your bottleneck.
- *
- * We've been building our expertise with this project since January 2002. We
- * promise spending a couple bucks [Euro, Yuan, Rupees, Galactic Credits] to
- * let us take over your shared e-mail headache is a worthwhile investment.
- * It will give you a sense of control over your in-box that you probably
- * haven't had since spammers found you in a game of "E-mail Address
- * Battleship". Miss. Miss. You sunk my in-box!
- *
- * A legitimate license entitles you to support, access to the developer
- * mailing list, the ability to participate in betas and the warm fuzzy
- * feeling of feeding a couple obsessed developers who want to help you get
- * more done than 'the other guy'.
- *
- * - Jeff Standen, Mike Fogg, Brenan Cavish, Darren Sugita, Dan Hildebrandt
- * and Joe Geck.
- * WEBGROUP MEDIA LLC. - Developers of Cerberus Helpdesk
- */
- class C4_ORMHelper extends DevblocksORMHelper {
- static public function qstr($str) {
- $db = DevblocksPlatform::getDatabaseService();
- return $db->qstr($str);
- }
-
- static protected function _appendSelectJoinSqlForCustomFieldTables($tables, $params, $key, $select_sql, $join_sql) {
- $custom_fields = DAO_CustomField::getAll();
- $field_ids = array();
-
- $return_multiple_values = false; // can our CF return more than one hit? (GROUP BY)
-
- if(is_array($tables))
- foreach($tables as $tbl_name => $null) {
- // Filter and sanitize
- if(substr($tbl_name,0,3) != "cf_" // not a custom field
- || 0 == ($field_id = intval(substr($tbl_name,3)))) // not a field_id
- continue;
- // Make sure the field exists for this source
- if(!isset($custom_fields[$field_id]))
- continue;
-
- $field_table = sprintf("cf_%d", $field_id);
- $value_table = '';
-
- // Join value by field data type
- switch($custom_fields[$field_id]->type) {
- case 'T': // multi-line CLOB
- $value_table = 'custom_field_clobvalue';
- break;
- case 'C': // checkbox
- case 'E': // date
- case 'N': // number
- case 'W': // worker
- $value_table = 'custom_field_numbervalue';
- break;
- default:
- case 'S': // single-line
- case 'D': // dropdown
- case 'U': // URL
- $value_table = 'custom_field_stringvalue';
- break;
- }
- $has_multiple_values = false;
- switch($custom_fields[$field_id]->type) {
- case Model_CustomField::TYPE_MULTI_PICKLIST:
- case Model_CustomField::TYPE_MULTI_CHECKBOX:
- $has_multiple_values = true;
- break;
- }
- // If we have multiple values but we don't need to WHERE the JOIN, be efficient and don't GROUP BY
- if(!isset($params['cf_'.$field_id])) {
- $select_sql .= sprintf(",(SELECT field_value FROM %s WHERE %s=source_id AND field_id=%d LIMIT 0,1) AS %s ",
- $value_table,
- $key,
- $field_id,
- $field_table
- );
-
- } else {
- $select_sql .= sprintf(", %s.field_value as %s ",
- $field_table,
- $field_table
- );
-
- $join_sql .= sprintf("LEFT JOIN %s %s ON (%s=%s.source_id AND %s.field_id=%d) ",
- $value_table,
- $field_table,
- $key,
- $field_table,
- $field_table,
- $field_id
- );
-
- // If we do need to WHERE this JOIN, make sure we GROUP BY
- if($has_multiple_values)
- $return_multiple_values = true;
- }
- }
-
- return array($select_sql, $join_sql, $return_multiple_values);
- }
- }
- /**
- * Global Settings DAO
- */
- class DAO_Setting extends DevblocksORMHelper {
- static function set($key, $value) {
- $db = DevblocksPlatform::getDatabaseService();
- $db->Replace('setting',array('setting'=>$db->qstr($key),'value'=>$db->qstr($value)),array('setting'),false);
- }
-
- static function get($key) {
- $db = DevblocksPlatform::getDatabaseService();
- $sql = sprintf("SELECT value FROM setting WHERE setting = %s",
- $db->qstr($key)
- );
- $value = $db->GetOne($sql) or die(__CLASS__ . ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
-
- return $value;
- }
-
- static function getSettings() {
- $cache = DevblocksPlatform::getCacheService();
- if(null === ($settings = $cache->load(CerberusApplication::CACHE_SETTINGS_DAO))) {
- $db = DevblocksPlatform::getDatabaseService();
- $settings = array();
-
- $sql = sprintf("SELECT setting,value FROM setting");
- $rs = $db->Execute($sql) or die(__CLASS__ . ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
-
- if(is_a($rs,'ADORecordSet'))
- while(!$rs->EOF) {
- $settings[$rs->Fields('setting')] = $rs->Fields('value');
- $rs->MoveNext();
- }
-
- $cache->save($settings, CerberusApplication::CACHE_SETTINGS_DAO);
- }
-
- return $settings;
- }
- };
- /**
- * Bayesian Anti-Spam DAO
- */
- class DAO_Bayes {
- private function DAO_Bayes() {}
-
- /**
- * @return CerberusWord[]
- */
- static function lookupWordIds($words) {
- $db = DevblocksPlatform::getDatabaseService();
- $tmp = array();
- $outwords = array(); // CerberusWord
-
- // Escaped set
- if(is_array($words))
- foreach($words as $word) {
- $tmp[] = $db->escape($word);
- }
-
- if(empty($words))
- return array();
-
- $sql = sprintf("SELECT id,word,spam,nonspam FROM bayes_words WHERE word IN ('%s')",
- implode("','", $tmp)
- );
- $rs = $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
-
- // [JAS]: Keep a list of words we can check off as we index them with IDs
- $tmp = array_flip($words); // words are now keys
-
- // Existing Words
- if(is_a($rs,'ADORecordSet'))
- while(!$rs->EOF) {
- $w = new CerberusBayesWord();
- $w->id = intval($rs->fields['id']);
- $w->word = mb_convert_case($rs->fields['word'], MB_CASE_LOWER);
- $w->spam = intval($rs->fields['spam']);
- $w->nonspam = intval($rs->fields['nonspam']);
-
- $outwords[mb_convert_case($w->word, MB_CASE_LOWER)] = $w;
- unset($tmp[$w->word]); // check off we've indexed this word
- $rs->MoveNext();
- }
-
- // Insert new words
- if(is_array($tmp))
- foreach($tmp as $new_word => $v) {
- $new_id = $db->GenID('bayes_words_seq');
- $sql = sprintf("INSERT INTO bayes_words (id,word) VALUES (%d,%s)",
- $new_id,
- $db->qstr($new_word)
- );
- $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
-
- $w = new CerberusBayesWord();
- $w->id = $new_id;
- $w->word = $new_word;
- $outwords[$w->word] = $w;
- }
-
- return $outwords;
- }
-
- /**
- * @return array Two element array (keys: spam,nonspam)
- */
- static function getStatistics() {
- $db = DevblocksPlatform::getDatabaseService();
-
- // [JAS]: [TODO] Change this into a 'replace' index?
- $sql = "SELECT spam, nonspam FROM bayes_stats";
- $rs = $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
-
- if($rs->NumRows()) {
- $spam = intval($rs->Fields('spam'));
- $nonspam = intval($rs->Fields('nonspam'));
- } else {
- $spam = 0;
- $nonspam = 0;
- $sql = "INSERT INTO bayes_stats (spam, nonspam) VALUES (0,0)";
- $db->Execute($sql);
- }
-
- return array('spam' => $spam,'nonspam' => $nonspam);
- }
-
- static function addOneToSpamTotal() {
- $db = DevblocksPlatform::getDatabaseService();
- $sql = "UPDATE bayes_stats SET spam = spam + 1";
- $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- }
-
- static function addOneToNonSpamTotal() {
- $db = DevblocksPlatform::getDatabaseService();
- $sql = "UPDATE bayes_stats SET nonspam = nonspam + 1";
- $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- }
-
- static function addOneToSpamWord($word_ids=array()) {
- if(!is_array($word_ids)) $word_ids = array($word_ids);
- if(empty($word_ids)) return;
- $db = DevblocksPlatform::getDatabaseService();
- $sql = sprintf("UPDATE bayes_words SET spam = spam + 1 WHERE id IN(%s)", implode(',',$word_ids));
- $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- }
-
- static function addOneToNonSpamWord($word_ids=array()) {
- if(!is_array($word_ids)) $word_ids = array($word_ids);
- if(empty($word_ids)) return;
- $db = DevblocksPlatform::getDatabaseService();
- $sql = sprintf("UPDATE bayes_words SET nonspam = nonspam + 1 WHERE id IN(%s)", implode(',',$word_ids));
- $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- }
-
- };
- /**
- * Worker DAO
- */
- class DAO_Worker extends C4_ORMHelper {
- private function DAO_Worker() {}
-
- const CACHE_ALL = 'ch_workers';
-
- const ID = 'id';
- const FIRST_NAME = 'first_name';
- const LAST_NAME = 'last_name';
- const TITLE = 'title';
- const EMAIL = 'email';
- const PASSWORD = 'pass';
- const IS_SUPERUSER = 'is_superuser';
- const IS_DISABLED = 'is_disabled';
- const LAST_ACTIVITY_DATE = 'last_activity_date';
- const LAST_ACTIVITY = 'last_activity';
-
- // [TODO] Convert to ::create($id, $fields)
- static function create($email, $password, $first_name, $last_name, $title) {
- if(empty($email) || empty($password))
- return null;
-
- $db = DevblocksPlatform::getDatabaseService();
- $id = $db->GenID('generic_seq');
-
- $sql = sprintf("INSERT INTO worker (id, email, pass, first_name, last_name, title, is_superuser, is_disabled) ".
- "VALUES (%d, %s, %s, %s, %s, %s,0,0)",
- $id,
- $db->qstr($email),
- $db->qstr(md5($password)),
- $db->qstr($first_name),
- $db->qstr($last_name),
- $db->qstr($title)
- );
- $rs = $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- self::clearCache();
-
- return $id;
- }
- static function clearCache() {
- $cache = DevblocksPlatform::getCacheService();
- $cache->remove(self::CACHE_ALL);
- }
-
- static function getAllActive() {
- return self::getAll(false, false);
- }
-
- static function getAllWithDisabled() {
- return self::getAll(false, true);
- }
-
- static function getAllOnline() {
- list($whos_online_workers, $null) = self::search(
- array(),
- array(
- new DevblocksSearchCriteria(SearchFields_Worker::LAST_ACTIVITY_DATE,DevblocksSearchCriteria::OPER_GT,(time()-60*15)), // idle < 15 mins
- new DevblocksSearchCriteria(SearchFields_Worker::LAST_ACTIVITY,DevblocksSearchCriteria::OPER_NOT_LIKE,'%translation_code";N;%'), // translation code not null (not just logged out)
- ),
- -1,
- 0,
- SearchFields_Worker::LAST_ACTIVITY_DATE,
- false,
- false
- );
-
- if(!empty($whos_online_workers))
- return self::getList(array_keys($whos_online_workers));
-
- return array();
- }
-
- static function getAll($nocache=false, $with_disabled=true) {
- $cache = DevblocksPlatform::getCacheService();
- if($nocache || null === ($workers = $cache->load(self::CACHE_ALL))) {
- $workers = self::getList();
- $cache->save($workers, self::CACHE_ALL);
- }
-
- /*
- * If the caller doesn't want disabled workers then remove them from the results,
- * but don't bother caching two different versions (always cache all)
- */
- if(!$with_disabled) {
- foreach($workers as $worker_id => $worker) { /* @var $worker CerberusWorker */
- if($worker->is_disabled)
- unset($workers[$worker_id]);
- }
- }
-
- return $workers;
- }
-
- static function getList($ids=array()) {
- if(!is_array($ids)) $ids = array($ids);
-
- $db = DevblocksPlatform::getDatabaseService();
- $workers = array();
-
- $sql = "SELECT a.id, a.first_name, a.last_name, a.email, a.pass, a.title, a.is_superuser, a.is_disabled, a.last_activity_date, a.last_activity ".
- "FROM worker a ".
- ((!empty($ids) ? sprintf("WHERE a.id IN (%s) ",implode(',',$ids)) : " ").
- "ORDER BY a.first_name, a.last_name "
- );
- $rs = $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
-
- if(is_a($rs,'ADORecordSet'))
- while(!$rs->EOF) {
- $worker = new CerberusWorker();
- $worker->id = intval($rs->fields['id']);
- $worker->first_name = $rs->fields['first_name'];
- $worker->last_name = $rs->fields['last_name'];
- $worker->email = $rs->fields['email'];
- $worker->pass = $rs->fields['pass'];
- $worker->title = $rs->fields['title'];
- $worker->is_superuser = intval($rs->fields['is_superuser']);
- $worker->is_disabled = intval($rs->fields['is_disabled']);
- $worker->last_activity_date = intval($rs->fields['last_activity_date']);
-
- if(!empty($rs->fields['last_activity']))
- $worker->last_activity = unserialize($rs->fields['last_activity']);
-
- $workers[$worker->id] = $worker;
- $rs->MoveNext();
- }
-
- return $workers;
- }
-
- /**
- * @return CerberusWorker
- */
- static function getAgent($id) {
- if(empty($id)) return null;
-
- $workers = self::getAllWithDisabled();
-
- if(isset($workers[$id]))
- return $workers[$id];
-
- return null;
- }
- /**
- * Enter description here...
- *
- * @param string $email
- * @return integer $id
- */
- static function lookupAgentEmail($email) {
- if(empty($email)) return null;
- $db = DevblocksPlatform::getDatabaseService();
-
- $sql = sprintf("SELECT a.id FROM worker a WHERE a.email = %s",
- $db->qstr($email)
- );
- $rs = $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
-
- if(is_a($rs,'ADORecordSet') && !$rs->EOF) {
- return intval($rs->fields['id']);
- }
-
- return null;
- }
-
- static function updateAgent($ids, $fields, $flush_cache=true) {
- if(!is_array($ids)) $ids = array($ids);
-
- $db = DevblocksPlatform::getDatabaseService();
- $sets = array();
-
- if(!is_array($fields) || empty($fields) || empty($ids))
- return;
-
- foreach($fields as $k => $v) {
- $sets[] = sprintf("%s = %s",
- $k,
- $db->qstr($v)
- );
- }
-
- $sql = sprintf("UPDATE worker SET %s WHERE id IN (%s)",
- implode(', ', $sets),
- implode(',', $ids)
- );
- $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
-
- if($flush_cache) {
- self::clearCache();
- }
- }
-
- static function maint() {
- $db = DevblocksPlatform::getDatabaseService();
- $logger = DevblocksPlatform::getConsoleLog();
-
- $sql = "DELETE QUICK view_rss FROM view_rss LEFT JOIN worker ON view_rss.worker_id = worker.id WHERE worker.id IS NULL";
- $db->Execute($sql);
- $logger->info('[Maint] Purged ' . $db->Affected_Rows() . ' view_rss records.');
-
- $sql = "DELETE QUICK worker_mail_forward FROM worker_mail_forward LEFT JOIN worker ON worker_mail_forward.worker_id = worker.id WHERE worker.id IS NULL";
- $db->Execute($sql);
-
- $logger->info('[Maint] Purged ' . $db->Affected_Rows() . ' worker_mail_forward records.');
-
- $sql = "DELETE QUICK worker_pref FROM worker_pref LEFT JOIN worker ON worker_pref.worker_id = worker.id WHERE worker.id IS NULL";
- $db->Execute($sql);
-
- $logger->info('[Maint] Purged ' . $db->Affected_Rows() . ' worker_pref records.');
-
- $sql = "DELETE QUICK worker_to_team FROM worker_to_team LEFT JOIN worker ON worker_to_team.agent_id = worker.id WHERE worker.id IS NULL";
- $db->Execute($sql);
-
- $logger->info('[Maint] Purged ' . $db->Affected_Rows() . ' worker_to_team records.');
-
- $sql = "DELETE QUICK worker_workspace_list FROM worker_workspace_list LEFT JOIN worker ON worker_workspace_list.worker_id = worker.id WHERE worker.id IS NULL";
- $db->Execute($sql);
-
- // [TODO] Clear out workers from any group_inbox_filter rows
-
- $logger->info('[Maint] Purged ' . $db->Affected_Rows() . ' worker_workspace_list records.');
- }
-
- static function deleteAgent($id) {
- if(empty($id)) return;
-
- // [TODO] Delete worker notes, comments, etc.
-
- /* This event fires before the delete takes place in the db,
- * so we can denote what is actually changing against the db state
- */
- $eventMgr = DevblocksPlatform::getEventService();
- $eventMgr->trigger(
- new Model_DevblocksEvent(
- 'worker.delete',
- array(
- 'worker_ids' => array($id),
- )
- )
- );
-
- $db = DevblocksPlatform::getDatabaseService();
-
- $sql = sprintf("DELETE QUICK FROM worker WHERE id = %d", $id);
- $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
-
- $sql = sprintf("DELETE QUICK FROM address_to_worker WHERE worker_id = %d", $id);
- $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
-
- $sql = sprintf("DELETE QUICK FROM worker_to_team WHERE agent_id = %d", $id);
- $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- $sql = sprintf("DELETE QUICK FROM view_rss WHERE worker_id = %d", $id);
- $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- $sql = sprintf("DELETE QUICK FROM worker_workspace_list WHERE worker_id = %d", $id);
- $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- // Clear assigned workers
- $sql = sprintf("UPDATE ticket SET next_worker_id = 0 WHERE next_worker_id = %d", $id);
- $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- // Clear roles
- $db->Execute(sprintf("DELETE FROM worker_to_role WHERE worker_id = %d", $id));
-
- // Invalidate caches
- self::clearCache();
- $cache = DevblocksPlatform::getCacheService();
- $cache->remove(DAO_Group::CACHE_ROSTERS);
- }
-
- static function login($email, $password) {
- $db = DevblocksPlatform::getDatabaseService();
- // [TODO] Uniquely salt hashes
- $sql = sprintf("SELECT id ".
- "FROM worker ".
- "WHERE is_disabled = 0 ".
- "AND email = %s ".
- "AND pass = MD5(%s)",
- $db->qstr($email),
- $db->qstr($password)
- );
- $worker_id = $db->GetOne($sql); // or die(__CLASS__ . ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- if(!empty($worker_id)) {
- return self::getAgent($worker_id);
- }
-
- return null;
- }
-
- static function setAgentTeams($agent_id, $team_ids) {
- if(!is_array($team_ids)) $team_ids = array($team_ids);
- if(empty($agent_id)) return;
- $db = DevblocksPlatform::getDatabaseService();
- $sql = sprintf("DELETE QUICK FROM worker_to_team WHERE agent_id = %d",
- $agent_id
- );
- $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
-
- foreach($team_ids as $team_id) {
- $sql = sprintf("INSERT INTO worker_to_team (agent_id, team_id) ".
- "VALUES (%d,%d)",
- $agent_id,
- $team_id
- );
- $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- }
-
- // Invalidate caches
- $cache = DevblocksPlatform::getCacheService();
- $cache->remove(DAO_Group::CACHE_ROSTERS);
- }
-
- /**
- * @return Model_TeamMember[]
- */
- static function getWorkerGroups($worker_id) {
- // Get the cache
- $rosters = DAO_Group::getRosters();
- $memberships = array();
-
- // Remove any groups our desired worker isn't in
- if(is_array($rosters))
- foreach($rosters as $group_id => $members) {
- if(isset($members[$worker_id])) {
- $memberships[$group_id] = $members[$worker_id];
- }
- }
-
- return $memberships;
- }
-
- /**
- * Store the workers last activity (provided by the page extension).
- *
- * @param integer $worker_id
- * @param Model_Activity $activity
- */
- static function logActivity($worker_id, Model_Activity $activity) {
- DAO_Worker::updateAgent($worker_id,array(
- DAO_Worker::LAST_ACTIVITY_DATE => time(),
- DAO_Worker::LAST_ACTIVITY => serialize($activity)
- ),false);
- }
- /**
- * Enter description here...
- *
- * @param DevblocksSearchCriteria[] $params
- * @param integer $limit
- * @param integer $page
- * @param string $sortBy
- * @param boolean $sortAsc
- * @param boolean $withCounts
- * @return array
- */
- static function search($columns, $params, $limit=10, $page=0, $sortBy=null, $sortAsc=null, $withCounts=true) {
- $db = DevblocksPlatform::getDatabaseService();
- $fields = SearchFields_Worker::getFields();
-
- // Sanitize
- if(!isset($fields[$sortBy]))
- $sortBy=null;
- list($tables,$wheres) = parent::_parseSearchParams($params, $columns, $fields, $sortBy);
- $start = ($page * $limit); // [JAS]: 1-based [TODO] clean up + document
- $total = -1;
-
- $select_sql = sprintf("SELECT ".
- "w.id as %s, ".
- "w.first_name as %s, ".
- "w.last_name as %s, ".
- "w.title as %s, ".
- "w.email as %s, ".
- "w.is_superuser as %s, ".
- "w.last_activity_date as %s, ".
- "w.is_disabled as %s ",
- SearchFields_Worker::ID,
- SearchFields_Worker::FIRST_NAME,
- SearchFields_Worker::LAST_NAME,
- SearchFields_Worker::TITLE,
- SearchFields_Worker::EMAIL,
- SearchFields_Worker::IS_SUPERUSER,
- SearchFields_Worker::LAST_ACTIVITY_DATE,
- SearchFields_Worker::IS_DISABLED
- );
-
- $join_sql = "FROM worker w ";
-
- // Custom field joins
- list($select_sql, $join_sql, $has_multiple_values) = self::_appendSelectJoinSqlForCustomFieldTables(
- $tables,
- $params,
- 'w.id',
- $select_sql,
- $join_sql
- );
-
- $where_sql = "".
- (!empty($wheres) ? sprintf("WHERE %s ",implode(' AND ',$wheres)) : "");
-
- $sort_sql = (!empty($sortBy)) ? sprintf("ORDER BY %s %s ",$sortBy,($sortAsc || is_null($sortAsc))?"ASC":"DESC") : " ";
-
- $sql =
- $select_sql.
- $join_sql.
- $where_sql.
- ($has_multiple_values ? 'GROUP BY w.id ' : '').
- $sort_sql;
-
- // [TODO] Could push the select logic down a level too
- if($limit > 0) {
- $rs = $db->SelectLimit($sql,$limit,$start) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- } else {
- $rs = $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- $total = $rs->RecordCount();
- }
-
- $results = array();
-
- if(is_a($rs,'ADORecordSet'))
- while(!$rs->EOF) {
- $result = array();
- foreach($rs->fields as $f => $v) {
- $result[$f] = $v;
- }
- $object_id = intval($rs->fields[SearchFields_Worker::ID]);
- $results[$object_id] = $result;
- $rs->MoveNext();
- }
- // [JAS]: Count all
- if($withCounts) {
- $count_sql =
- ($has_multiple_values ? "SELECT COUNT(DISTINCT w.id) " : "SELECT COUNT(w.id) ").
- $join_sql.
- $where_sql;
- $total = $db->GetOne($count_sql);
- }
-
- return array($results,$total);
- }
-
- };
- /**
- * ...
- *
- */
- class SearchFields_Worker implements IDevblocksSearchFields {
- // Worker
- const ID = 'w_id';
- const FIRST_NAME = 'w_first_name';
- const LAST_NAME = 'w_last_name';
- const TITLE = 'w_title';
- const EMAIL = 'w_email';
- const IS_SUPERUSER = 'w_is_superuser';
- const LAST_ACTIVITY = 'w_last_activity';
- const LAST_ACTIVITY_DATE = 'w_last_activity_date';
- const IS_DISABLED = 'w_is_disabled';
-
- /**
- * @return DevblocksSearchField[]
- */
- static function getFields() {
- $translate = DevblocksPlatform::getTranslationService();
-
- $columns = array(
- self::ID => new DevblocksSearchField(self::ID, 'w', 'id', null, $translate->_('common.id')),
- self::FIRST_NAME => new DevblocksSearchField(self::FIRST_NAME, 'w', 'first_name', null, $translate->_('worker.first_name')),
- self::LAST_NAME => new DevblocksSearchField(self::LAST_NAME, 'w', 'last_name', null, $translate->_('worker.last_name')),
- self::TITLE => new DevblocksSearchField(self::TITLE, 'w', 'title', null, $translate->_('worker.title')),
- self::EMAIL => new DevblocksSearchField(self::EMAIL, 'w', 'email', null, ucwords($translate->_('common.email'))),
- self::IS_SUPERUSER => new DevblocksSearchField(self::IS_SUPERUSER, 'w', 'is_superuser', null, $translate->_('worker.is_superuser')),
- self::LAST_ACTIVITY => new DevblocksSearchField(self::LAST_ACTIVITY, 'w', 'last_activity', null, $translate->_('worker.last_activity')),
- self::LAST_ACTIVITY_DATE => new DevblocksSearchField(self::LAST_ACTIVITY_DATE, 'w', 'last_activity_date', null, $translate->_('worker.last_activity_date')),
- self::IS_DISABLED => new DevblocksSearchField(self::IS_DISABLED, 'w', 'is_disabled', null, ucwords($translate->_('common.disabled'))),
- );
-
- // Custom Fields
- $fields = DAO_CustomField::getBySource(ChCustomFieldSource_Worker::ID);
- if(is_array($fields))
- foreach($fields as $field_id => $field) {
- $key = 'cf_'.$field_id;
- $columns[$key] = new DevblocksSearchField($key,$key,'field_value',null,$field->name);
- }
-
- // Sort by label (translation-conscious)
- uasort($columns, create_function('$a, $b', "return strcasecmp(\$a->db_label,\$b->db_label);\n"));
- return $columns;
- }
- };
- class DAO_WorkerRole extends DevblocksORMHelper {
- const _CACHE_ALL = 'ch_acl';
-
- const CACHE_KEY_ROLES = 'roles';
- const CACHE_KEY_PRIVS_BY_ROLE = 'privs_by_role';
- const CACHE_KEY_WORKERS_BY_ROLE = 'workers_by_role';
- const CACHE_KEY_PRIVS_BY_WORKER = 'privs_by_worker';
-
- const ID = 'id';
- const NAME = 'name';
- static function create($fields) {
- $db = DevblocksPlatform::getDatabaseService();
-
- $id = $db->GenID('generic_seq');
-
- $sql = sprintf("INSERT INTO worker_role (id) ".
- "VALUES (%d)",
- $id
- );
- $db->Execute($sql);
-
- self::update($id, $fields);
-
- return $id;
- }
-
- static function update($ids, $fields) {
- parent::_update($ids, 'worker_role', $fields);
- }
-
- static function getACL($nocache=false) {
- $cache = DevblocksPlatform::getCacheService();
- if($nocache || null === ($acl = $cache->load(self::_CACHE_ALL))) {
- $db = DevblocksPlatform::getDatabaseService();
-
- // All roles
- $all_roles = self::getWhere();
- $all_worker_ids = array();
- // All privileges by role
- $all_privs = array();
- $rs = $db->Execute("SELECT role_id, priv_id FROM worker_role_acl WHERE has_priv = 1 ORDER BY role_id, priv_id");
- while(!$rs->EOF) {
- $role_id = intval($rs->fields['role_id']);
- $priv_id = $rs->fields['priv_id'];
- if(!isset($all_privs[$role_id]))
- $all_privs[$role_id] = array();
-
- $all_privs[$role_id][$priv_id] = $priv_id;
- $rs->MoveNext();
- }
-
- // All workers by role
- $all_rosters = array();
- $rs = $db->Execute("SELECT role_id, worker_id FROM worker_to_role");
- while(!$rs->EOF) {
- $role_id = intval($rs->fields['role_id']);
- $worker_id = intval($rs->fields['worker_id']);
- if(!isset($all_rosters[$role_id]))
- $all_rosters[$role_id] = array();
- $all_rosters[$role_id][$worker_id] = $worker_id;
- $all_worker_ids[$worker_id] = $worker_id;
- $rs->MoveNext();
- }
-
- // Aggregate privs by workers' roles (if set anywhere, keep)
- $privs_by_worker = array();
- if(is_array($all_worker_ids))
- foreach($all_worker_ids as $worker_id) {
- if(!isset($privs_by_worker[$worker_id]))
- $privs_by_worker[$worker_id] = array();
-
- foreach($all_rosters as $role_id => $role_roster) {
- if(isset($role_roster[$worker_id]) && isset($all_privs[$role_id])) {
- // If we have privs from other groups, merge on the keys
- $current_privs = (is_array($privs_by_worker[$worker_id])) ? $privs_by_worker[$worker_id] : array();
- $privs_by_worker[$worker_id] = array_merge($current_privs,$all_privs[$role_id]);
- }
- }
- }
-
- $acl = array(
- self::CACHE_KEY_ROLES => $all_roles,
- self::CACHE_KEY_PRIVS_BY_ROLE => $all_privs,
- self::CACHE_KEY_WORKERS_BY_ROLE => $all_rosters,
- self::CACHE_KEY_PRIVS_BY_WORKER => $privs_by_worker,
- );
-
- $cache->save($acl, self::_CACHE_ALL);
- }
-
- return $acl;
-
- }
-
- /**
- * @param string $where
- * @return Model_WorkerRole[]
- */
- static function getWhere($where=null) {
- $db = DevblocksPlatform::getDatabaseService();
-
- $sql = "SELECT id, name ".
- "FROM worker_role ".
- (!empty($where) ? sprintf("WHERE %s ",$where) : "").
- "ORDER BY name asc";
- $rs = $db->Execute($sql);
-
- return self::_getObjectsFromResult($rs);
- }
- /**
- * @param integer $id
- * @return Model_WorkerRole */
- static function get($id) {
- $objects = self::getWhere(sprintf("%s = %d",
- self::ID,
- $id
- ));
-
- if(isset($objects[$id]))
- return $objects[$id];
-
- return null;
- }
-
- /**
- * @param ADORecordSet $rs
- * @return Model_WorkerRole[]
- */
- static private function _getObjectsFromResult($rs) {
- $objects = array();
-
- while(!$rs->EOF) {
- $object = new Model_WorkerRole();
- $object->id = $rs->fields['id'];
- $object->name = $rs->fields['name'];
- $objects[$object->id] = $object;
- $rs->MoveNext();
- }
-
- return $objects;
- }
-
- static function delete($ids) {
- if(!is_array($ids)) $ids = array($ids);
- $db = DevblocksPlatform::getDatabaseService();
-
- if(empty($ids))
- return;
-
- $ids_list = implode(',', $ids);
-
- $db->Execute(sprintf("DELETE FROM worker_role WHERE id IN (%s)", $ids_list));
- $db->Execute(sprintf("DELETE FROM worker_to_role WHERE role_id IN (%s)", $ids_list));
- $db->Execute(sprintf("DELETE FROM worker_role_acl WHERE role_id IN (%s)", $ids_list));
-
- return true;
- }
-
- static function getRolePrivileges($role_id) {
- $acl = self::getACL();
-
- if(empty($role_id) || !isset($acl[self::CACHE_KEY_PRIVS_BY_ROLE][$role_id]))
- return array();
-
- return $acl[self::CACHE_KEY_PRIVS_BY_ROLE][$role_id];
- }
-
- /**
- * @param integer $role_id
- * @param array $privileges
- * @param boolean $replace
- */
- static function setRolePrivileges($role_id, $privileges) {
- if(!is_array($privileges)) $privileges = array($privileges);
- $db = DevblocksPlatform::getDatabaseService();
-
- if(empty($role_id))
- return;
-
- // Wipe all privileges on blank replace
- $sql = sprintf("DELETE FROM worker_role_acl WHERE role_id = %d", $role_id);
- $db->Execute($sql);
- // Load entire ACL list
- $acl = DevblocksPlatform::getAclRegistry();
-
- // Set ACLs according to the new master list
- if(!empty($privileges) && !empty($acl)) {
- foreach($privileges as $priv) { /* @var $priv DevblocksAclPrivilege */
- $sql = sprintf("INSERT INTO worker_role_acl (role_id, priv_id, has_priv) ".
- "VALUES (%d, %s, %d)",
- $role_id,
- $db->qstr($priv),
- 1
- );
- $db->Execute($sql);
- }
- }
-
- unset($privileges);
-
- self::clearCache();
- }
-
- static function getRoleWorkers($role_id) {
- $acl = self::getACL();
-
- if(empty($role_id) || !isset($acl[self::CACHE_KEY_WORKERS_BY_ROLE][$role_id]))
- return array();
-
- return $acl[self::CACHE_KEY_WORKERS_BY_ROLE][$role_id];
- }
-
- static function setRoleWorkers($role_id, $worker_ids) {
- if(!is_array($worker_ids)) $worker_ids = array($worker_ids);
- $db = DevblocksPlatform::getDatabaseService();
-
- if(empty($role_id))
- return;
-
- // Wipe roster
- $sql = sprintf("DELETE FROM worker_to_role WHERE role_id = %d", $role_id);
- $db->Execute($sql);
-
- // Add desired workers to role's roster
- if(is_array($worker_ids))
- foreach($worker_ids as $worker_id) {
- $sql = sprintf("INSERT INTO worker_to_role (worker_id, role_id) ".
- "VALUES (%d, %d)",
- $worker_id,
- $role_id
- );
- $db->Execute($sql);
- }
-
- self::clearCache();
- }
-
- static function clearCache() {
- $cache = DevblocksPlatform::getCacheService();
- $cache->remove(self::_CACHE_ALL);
- }
- };
- class DAO_WorkerEvent extends DevblocksORMHelper {
- const CACHE_COUNT_PREFIX = 'workerevent_count_';
-
- const ID = 'id';
- const CREATED_DATE = 'created_date';
- const WORKER_ID = 'worker_id';
- const TITLE = 'title';
- const CONTENT = 'content';
- const IS_READ = 'is_read';
- const URL = 'url';
- static function create($fields) {
- $db = DevblocksPlatform::getDatabaseService();
-
- $id = $db->GenID('worker_event_seq');
-
- $sql = sprintf("INSERT INTO worker_event (id) ".
- "VALUES (%d)",
- $id
- );
- $db->Execute($sql);
-
- self::update($id, $fields);
-
- // Invalidate the worker notification count cache
- if(isset($fields[self::WORKER_ID])) {
- $cache = DevblocksPlatform::getCacheService();
- self::clearCountCache($fields[self::WORKER_ID]);
- }
-
- return $id;
- }
-
- static function update($ids, $fields) {
- parent::_update($ids, 'worker_event', $fields);
- }
-
- static function updateWhere($fields, $where) {
- parent::_updateWhere('worker_event', $fields, $where);
- }
-
- /**
- * @param string $where
- * @return Model_WorkerEvent[]
- */
- static function getWhere($where=null) {
- $db = DevblocksPlatform::getDatabaseService();
-
- $sql = "SELECT id, created_date, worker_id, title, content, is_read, url ".
- "FROM worker_event ".
- (!empty($where) ? sprintf("WHERE %s ",$where) : "").
- "ORDER BY id asc";
- $rs = $db->Execute($sql);
-
- return self::_getObjectsFromResult($rs);
- }
- /**
- * @param integer $id
- * @return Model_WorkerEvent */
- static function get($id) {
- $objects = self::getWhere(sprintf("%s = %d",
- self::ID,
- $id
- ));
-
- if(isset($objects[$id]))
- return $objects[$id];
-
- return null;
- }
-
- static function getUnreadCountByWorker($worker_id) {
- $db = DevblocksPlatform::getDatabaseService();
- $cache = DevblocksPlatform::getCacheService();
-
- if(null === ($count = $cache->load(self::CACHE_COUNT_PREFIX.$worker_id))) {
- $sql = sprintf("SELECT count(*) ".
- "FROM worker_event ".
- "WHERE worker_id = %d ".
- "AND is_read = 0",
- $worker_id
- );
-
- $count = $db->GetOne($sql);
- $cache->save($count, self::CACHE_COUNT_PREFIX.$worker_id);
- }
-
- return intval($count);
- }
-
- /**
- * @param ADORecordSet $rs
- * @return Model_WorkerEvent[]
- */
- static private function _getObjectsFromResult($rs) {
- $objects = array();
-
- while(!$rs->EOF) {
- $object = new Model_WorkerEvent();
- $object->id = $rs->fields['id'];
- $object->created_date = $rs->fields['created_date'];
- $object->worker_id = $rs->fields['worker_id'];
- $object->title = $rs->fields['title'];
- $object->url = $rs->fields['url'];
- $object->content = $rs->fields['content'];
- $object->is_read = $rs->fields['is_read'];
- $objects[$object->id] = $object;
- $rs->MoveNext();
- }
-
- return $objects;
- }
-
- static function delete($ids) {
- if(!is_array($ids)) $ids = array($ids);
- $db = DevblocksPlatform::getDatabaseService();
-
- if(empty($ids))
- return;
-
- $ids_list = implode(',', $ids);
-
- $db->Execute(sprintf("DELETE FROM worker_event WHERE id IN (%s)", $ids_list));
-
- return true;
- }
- static function clearCountCache($worker_id) {
- $cache = DevblocksPlatform::getCacheService();
- $cache->remove(self::CACHE_COUNT_PREFIX.$worker_id);
- }
- /**
- * Enter description here...
- *
- * @param DevblocksSearchCriteria[] $params
- * @param integer $limit
- * @param integer $page
- * @param string $sortBy
- * @param boolean $sortAsc
- * @param boolean $withCounts
- * @return array
- */
- static function search($params, $limit=10, $page=0, $sortBy=null, $sortAsc=null, $withCounts=true) {
- $db = DevblocksPlatform::getDatabaseService();
- $fields = SearchFields_WorkerEvent::getFields();
-
- // Sanitize
- if(!isset($fields[$sortBy]))
- $sortBy=null;
- list($tables,$wheres) = parent::_parseSearchParams($params, array(),$fields,$sortBy);
- $start = ($page * $limit); // [JAS]: 1-based [TODO] clean up + document
- $total = -1;
-
- $sql = sprintf("SELECT ".
- "we.id as %s, ".
- "we.created_date as %s, ".
- "we.worker_id as %s, ".
- "we.title as %s, ".
- "we.content as %s, ".
- "we.is_read as %s, ".
- "we.url as %s ".
- "FROM worker_event we ",
- // "INNER JOIN team tm ON (tm.id = t.team_id) ".
- SearchFields_WorkerEvent::ID,
- SearchFields_WorkerEvent::CREATED_DATE,
- SearchFields_WorkerEvent::WORKER_ID,
- SearchFields_WorkerEvent::TITLE,
- SearchFields_WorkerEvent::CONTENT,
- SearchFields_WorkerEvent::IS_READ,
- SearchFields_WorkerEvent::URL
- ).
-
- // [JAS]: Dynamic table joins
- // (isset($tables['ra']) ? "INNER JOIN requester r ON (r.ticket_id=t.id)" : " ").
-
- (!empty($wheres) ? sprintf("WHERE %s ",implode(' AND ',$wheres)) : "").
- (!empty($sortBy) ? sprintf("ORDER BY %s %s",$sortBy,($sortAsc || is_null($sortAsc))?"ASC":"DESC") : "")
- ;
- // [TODO] Could push the select logic down a level too
- if($limit > 0) {
- $rs = $db->SelectLimit($sql,$limit,$start) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- } else {
- $rs = $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- $total = $rs->RecordCount();
- }
-
- $results = array();
-
- if(is_a($rs,'ADORecordSet'))
- while(!$rs->EOF) {
- $result = array();
- foreach($rs->fields as $f => $v) {
- $result[$f] = $v;
- }
- $ticket_id = intval($rs->fields[SearchFields_WorkerEvent::ID]);
- $results[$ticket_id] = $result;
- $rs->MoveNext();
- }
- // [JAS]: Count all
- if($withCounts) {
- $rs = $db->Execute($sql);
- $total = $rs->RecordCount();
- }
-
- return array($results,$total);
- }
-
- };
- class SearchFields_WorkerEvent implements IDevblocksSearchFields {
- // Worker Event
- const ID = 'we_id';
- const CREATED_DATE = 'we_created_date';
- const WORKER_ID = 'we_worker_id';
- const TITLE = 'we_title';
- const CONTENT = 'we_content';
- const IS_READ = 'we_is_read';
- const URL = 'we_url';
-
- /**
- * @return DevblocksSearchField[]
- */
- static function getFields() {
- $translate = DevblocksPlatform::getTranslationService();
-
- $columns = array(
- self::ID => new DevblocksSearchField(self::ID, 'we', 'id', null, $translate->_('worker_event.id')),
- self::CREATED_DATE => new DevblocksSearchField(self::CREATED_DATE, 'we', 'created_date', null, $translate->_('worker_event.created_date')),
- self::WORKER_ID => new DevblocksSearchField(self::WORKER_ID, 'we', 'worker_id', null, $translate->_('worker_event.worker_id')),
- self::TITLE => new DevblocksSearchField(self::TITLE, 'we', 'title', null, $translate->_('worker_event.title')),
- self::CONTENT => new DevblocksSearchField(self::CONTENT, 'we', 'content', null, $translate->_('worker_event.content')),
- self::IS_READ => new DevblocksSearchField(self::IS_READ, 'we', 'is_read', null, $translate->_('worker_event.is_read')),
- self::URL => new DevblocksSearchField(self::URL, 'we', 'url', null, $translate->_('common.url')),
- );
-
- // Sort by label (translation-conscious)
- uasort($columns, create_function('$a, $b', "return strcasecmp(\$a->db_label,\$b->db_label);\n"));
- return $columns;
- }
- };
- class DAO_ContactOrg extends C4_ORMHelper {
- const ID = 'id';
- const NAME = 'name';
- const STREET = 'street';
- const CITY = 'city';
- const PROVINCE = 'province';
- const POSTAL = 'postal';
- const COUNTRY = 'country';
- const PHONE = 'phone';
- const WEBSITE = 'website';
- const CREATED = 'created';
-
- private function __construct() {}
-
- public static function getFields() {
- $translate = DevblocksPlatform::getTranslationService();
- return array(
- 'id' => $translate->_('contact_org.id'),
- 'name' => $translate->_('contact_org.name'),
- 'street' => $translate->_('contact_org.street'),
- 'city' => $translate->_('contact_org.city'),
- 'province' => $translate->_('contact_org.province'),
- 'postal' => $translate->_('contact_org.postal'),
- 'country' => $translate->_('contact_org.country'),
- 'phone' => $translate->_('contact_org.phone'),
- 'website' => $translate->_('contact_org.website'),
- 'created' => $translate->_('contact_org.created'),
- );
- }
-
- /**
- * Enter description here...
- *
- * @param array $fields
- * @return integer
- */
- static function create($fields) {
- $db = DevblocksPlatform::getDatabaseService();
- $id = $db->GenID('contact_org_seq');
-
- $sql = sprintf("INSERT INTO contact_org (id,name,street,city,province,postal,country,phone,website,created) ".
- "VALUES (%d,'','','','','','','','',%d)",
- $id,
- time()
- );
- $rs = $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
-
- self::update($id, $fields);
- return $id;
- }
-
- /**
- * Enter description here...
- *
- * @param array $ids
- * @param array $fields
- * @return Model_ContactOrg
- */
- static function update($ids, $fields) {
- if(!is_array($ids)) $ids = array($ids);
- parent::_update($ids, 'contact_org', $fields);
- }
-
- /**
- * @param array $ids
- */
- static function delete($ids) {
- if(!is_array($ids)) $ids = array($ids);
- $db = DevblocksPlatform::getDatabaseService();
-
- if(empty($ids))
- return;
-
- $id_list = implode(',', $ids);
-
- // Orgs
- $sql = sprintf("DELETE QUICK FROM contact_org WHERE id IN (%s)",
- $id_list
- );
- $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- // Clear any associated addresses
- $sql = sprintf("UPDATE address SET contact_org_id = 0 WHERE contact_org_id IN (%s)",
- $id_list
- );
- $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
-
- // Tasks
- DAO_Task::deleteBySourceIds('cerberusweb.tasks.org', $ids);
-
- // Custom fields
- DAO_CustomFieldValue::deleteBySourceIds(ChCustomFieldSource_Org::ID, $ids);
- // Notes
- DAO_Note::deleteBySourceIds(ChNotesSource_Org::ID, $ids);
- }
-
- /**
- * @param string $where
- * @return Model_ContactOrg[]
- */
- static function getWhere($where=null) {
- $db = DevblocksPlatform::getDatabaseService();
-
- $sql = "SELECT id,name,street,city,province,postal,country,phone,website,created ".
- "FROM contact_org ".
- (!empty($where) ? sprintf("WHERE %s ", $where) : " ")
- ;
- $rs = $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- return self::_getObjectsFromResultSet($rs);
- }
-
- static private function _getObjectsFromResultSet($rs) {
- $objects = array();
-
- if(is_a($rs,'ADORecordSet'))
- while(!$rs->EOF) {
- $object = new Model_ContactOrg();
- $object->id = intval($rs->fields['id']);
- $object->name = $rs->fields['name'];
- $object->street = $rs->fields['street'];
- $object->city = $rs->fields['city'];
- $object->province = $rs->fields['province'];
- $object->postal = $rs->fields['postal'];
- $object->country = $rs->fields['country'];
- $object->phone = $rs->fields['phone'];
- $object->website = $rs->fields['website'];
- $object->created = intval($rs->fields['created']);
- $objects[$object->id] = $object;
- $rs->MoveNext();
- }
-
- return $objects;
- }
-
- /**
- * @param integer $id
- * @return Model_ContactOrg
- */
- static function get($id) {
- $where = sprintf("%s = %d",
- self::ID,
- $id
- );
- $objects = self::getWhere($where);
- if(isset($objects[$id]))
- return $objects[$id];
-
- return null;
- }
- /**
- * Enter description here...
- *
- * @param string $name
- * @param boolean $create_if_null
- * @return Model_ContactOrg
- */
- static function lookup($name, $create_if_null=false) {
- $db = DevblocksPlatform::getDatabaseService();
-
- @$orgs = self::getWhere(
- sprintf('%s = %s', self::NAME, $db->qstr($name))
- );
-
- if(empty($orgs)) {
- if($create_if_null) {
- $fields = array(
- self::NAME => $name
- );
- return self::create($fields);
- }
- } else {
- return key($orgs);
- }
-
- return NULL;
- }
-
- /**
- * Enter description here...
- *
- * @param DevblocksSearchCriteria[] $params
- * @param integer $limit
- * @param integer $page
- * @param string $sortBy
- * @param boolean $sortAsc
- * @param boolean $withCounts
- * @return array
- */
- static function search($columns, $params, $limit=10, $page=0, $sortBy=null, $sortAsc=null, $withCounts=true) {
- $db = DevblocksPlatform::getDatabaseService();
- $fields = SearchFields_ContactOrg::getFields();
-
- // Sanitize
- if(!isset($fields[$sortBy]))
- $sortBy=null;
-
- list($tables,$wheres) = parent::_parseSearchParams($params, $columns, $fields,$sortBy);
- $start = ($page * $limit); // [JAS]: 1-based [TODO] clean up + document
- $total = -1;
-
- $select_sql = sprintf("SELECT ".
- "c.id as %s, ".
- "c.name as %s, ".
- "c.street as %s, ".
- "c.city as %s, ".
- "c.province as %s, ".
- "c.postal as %s, ".
- "c.country as %s, ".
- "c.phone as %s, ".
- "c.website as %s, ".
- "c.created as %s ",
- // "INNER JOIN team tm ON (tm.id = t.team_id) ".
- SearchFields_ContactOrg::ID,
- SearchFields_ContactOrg::NAME,
- SearchFields_ContactOrg::STREET,
- SearchFields_ContactOrg::CITY,
- SearchFields_ContactOrg::PROVINCE,
- SearchFields_ContactOrg::POSTAL,
- SearchFields_ContactOrg::COUNTRY,
- SearchFields_ContactOrg::PHONE,
- SearchFields_ContactOrg::WEBSITE,
- SearchFields_ContactOrg::CREATED
- );
-
- $join_sql = 'FROM contact_org c ';
- // Custom field joins
- list($select_sql, $join_sql, $has_multiple_values) = self::_appendSelectJoinSqlForCustomFieldTables(
- $tables,
- $params,
- 'c.id',
- $select_sql,
- $join_sql
- );
-
- $where_sql = "".
- (!empty($wheres) ? sprintf("WHERE %s ",implode(' AND ',$wheres)) : "");
-
- $sort_sql = (!empty($sortBy)) ? sprintf("ORDER BY %s %s ",$sortBy,($sortAsc || is_null($sortAsc))?"ASC":"DESC") : " ";
-
- $sql =
- $select_sql.
- $join_sql.
- $where_sql.
- ($has_multiple_values ? 'GROUP BY c.id ' : '').
- $sort_sql;
-
- // [TODO] Could push the select logic down a level too
- if($limit > 0) {
- $rs = $db->SelectLimit($sql,$limit,$start) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- } else {
- $rs = $db->Execute($sql) or die(__CLASS__ . '('.__LINE__.')'. ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */
- $total = $rs->RecordCount();
- }
-
- $results = array();
-
- if(is_a($rs,'ADORecordSet'))
- while(!$rs->EOF) {
- $result = array();
- foreach($rs->fields as $f => $v) {
- $result[$f] = $v;
- }
- $ticket_id = intval($rs->fields[SearchFields_ContactOrg::ID]);
- $results[$ticket_id] = $result;
- $rs->MoveNext();
- }
- // [JAS]: Count all
- if($withCounts) {
- $count_sql =
- ($has_multiple_values ? "SELECT COUNT(DISTINCT c.id) " : "SELECT COUNT(c.id) ").
- $join_sql.
- $where_sql;
- $total = $db->GetOne($count_sql);
- }
-
- return array($results,$total);
- }
- };
- class SearchFields_ContactOrg {
- const ID = 'c_id';
- const NAME = 'c_name';
- const STREET = 'c_street';
- const CITY = 'c_city';
- const PROVINCE = 'c_province';
- const POSTAL = 'c_postal';
- const COUNTRY = 'c_country';
- const PHONE = 'c_phone';
- const WEBSITE = 'c_website';
- const CREATED = 'c_created';
-
- /**
- * @return DevblocksSearchField[]
- */
- static function getFields() {
- $translate = DevblocksPlatform::getTranslationService();
-
- $columns = array(
- self::ID => new DevblocksSearchField(self::ID, 'c', 'id', null, $translate->_('contact_org.id')),
- self::NAME => new DevblocksSearchField(self::NAME, 'c', 'name', null, $translate->_('contact_org.name')),
- self::STREET => new DevblocksSearchField(self::STREET, 'c', 'street', null, $translate->_('contact_org.street')),
- self::CITY => new DevblocksSearchField(self::CITY, 'c', 'city', null, $translate->_('contact_org.city')),
- self::PROVINCE => new DevblocksSearchField(self::PROVINCE, 'c', 'province', null, $translate->_('contact_org.province')),
- self::POSTAL => new DevblocksSearchField(self::POSTAL, 'c', 'postal', null, $translate->_('contact_org.postal')),
- self::COUNTRY => new DevblocksSearchField(self::COUNTRY, 'c', 'country', null, $translate->_('contact_org.country')),
- self::PHONE => new DevblocksSearchField(self::PHONE, 'c', 'phone', null, $translate->_('contact_org.phone')),
- self::WEBSITE => new DevblocksSearchField(self::WEBSITE, 'c', 'website', null, $translate->_('contact_org.website')),
- self::CREATED => new DevblocksSearchField(self::CREATED, 'c', 'created', null, $translate->_('contact_org.created')),
- );
-
- // Custom Fields
- $fields = DAO_CustomField::getBySource(ChCustomFieldSource_Org::ID);
- if(is_array($fields))
- foreach($fields as $field_id => $field) {
- $key = 'cf_'.$field_id;
- $columns[$key] = new DevblocksSearchField($key,$key,'field_value',null,$field->name);
- }
-
- // Sort by label (translation-conscious)
- uasort($columns, create_function('$a, $b', "return strcasecmp(\$a->db_label,\$b->db_label);\n"));
-
- return $columns;
- }
- };
- /**
- * Address DAO
- *
- */
- class DAO_Address extends C4_ORMHelper {
- const ID = 'id';
- const EMAIL = 'email';
- const FIRST_NAME = 'first_name';
- const LAST_NAM…
Large files files are truncated, but you can click here to view the full file