/** * Initialize a new user filter on an active record. * It uses the table name and the database adapter from the Active Record. * * @param Phprojekt_ActiveRecord_Abstract $record An active record. * @param string $identifier The identifier usually the column to filter. * @param mixed $value The value to filter. * * @return void */ public function __construct(Phprojekt_ActiveRecord_Abstract $record, $identifier, $value) { $info = $record->info(); $cols = $info['cols']; $identifier = Phprojekt_ActiveRecord_Abstract::convertVarToSql($identifier); if (!in_array($identifier, $cols)) { throw new InvalidArgumentException('Identifier not found'); } $this->_identifier = $identifier; $this->_value = $value; parent::__construct($record->getAdapter()); }
/** * Get a value. * * @param string $name Name of the field. * * @return mix Value of the var. */ public function __get($name) { $name = Phprojekt_ActiveRecord_Abstract::convertVarToSql($name); if (!is_null($this->_metadata) && isset($this->_metadata->{$name})) { return $this->_metadata->{$name}; } return null; }
/** * This function is copied from the database manager because Phprojekt_Item_Abstract mistakenly expects * it to be a database manager. */ public function getInfo($order, $column) { $column = Phprojekt_ActiveRecord_Abstract::convertVarFromSql($column); $fields = $this->_getFields(); $result = array(); foreach ($fields as $field) { if (isset($field->{$column})) { $result[] = $field->{$column}; } } return $result; }
/** * Check if the user has delete access to the item if is not a global module. * * @param Phprojekt_ActiveRecord_Abstract $model The model to save. * @param string $moduleName The current module. * * @return boolean True for a valid right. */ private static function _checkItemRights($model, $moduleName) { $canDelete = false; if ($moduleName == 'Core') { return Phprojekt_Auth::isAdminUser(); } else { if (Phprojekt_Module::saveTypeIsNormal(Phprojekt_Module::getId($moduleName))) { $itemRights = $model->getRights(); if (isset($itemRights['currentUser'])) { if (!$itemRights['currentUser']['delete'] && !$itemRights['currentUser']['admin']) { $canDelete = false; } else { $canDelete = true; } } } else { $canDelete = true; } } return $canDelete; }
/** * Save is handled by parent. * * @return boolean True for a sucessful save. */ public function save() { $db = $this->getAdapter(); if (trim($this->sortOrder) == '' || is_null($this->sortOrder) || !$this->sortOrder) { // We don't have a sort order yet, most probably a brand-new record. // Detect highest available sort order up until now and use next-higher number. $sql = 'SELECT MAX(' . $db->quoteIdentifier('sort_order') . ') FROM ' . $db->quoteIdentifier($this->getTableName()) . ' WHERE ' . $db->quoteIdentifier('minutes_id') . ' = ?'; $result = $db->fetchCol($sql, $this->_minutesId); $maxSort = $result[0]; if (!$maxSort || $maxSort < 0) { $maxSort = 0; } $this->sortOrder = $maxSort + 1; } elseif (is_numeric($this->sortOrder) && $this->sortOrder > 0) { if (!isset($this->_history['sortOrder']) || isset($this->_history['sortOrder']) && $this->_history['sortOrder'] != $this->sortOrder) { // A sort order was given and differs from the initial value. We need to increment // all sort order values equal or above the new value by one, and then update this // record with the new value. That should ensure order value consistency. $data = array('sort_order' => new Zend_Db_Expr($this->_db->quoteIdentifier('sort_order') . ' + 1')); $where = sprintf('%s = %d and %s >= %d', $this->_db->quoteIdentifier('minutes_id'), $this->_minutesId, $this->_db->quoteIdentifier('sort_order'), $this->sortOrder); $this->update($data, $where); } } return parent::save(); }
/** * We translate the names of two classes into a relation table. * Its always {CLASS1}_{CLASS2}_rel while the classes are sorted in alphabetic order. * * @param string $myObject Own class. * @param string $foreignObject Foreign class. * * @return string Relation name. */ protected static function _translateIntoRelationTableName(Phprojekt_ActiveRecord_Abstract $myObject, Phprojekt_ActiveRecord_Abstract $foreignObject) { $tableNames = array(); $myTable = $myObject->getTableName(); $foreignTable = $foreignObject->getTableName(); $tableNames[] = $myTable; $tableNames[] = $foreignTable; sort($tableNames); reset($tableNames); $tableName = sprintf('%s_relation', implode('_', $tableNames)); return $tableName; }
/** * Extencion of the ActiveRecord save adding default permissions. * * @return boolean True for a sucessful save. */ public function save() { if ($this->id == 0) { if (parent::save()) { // adding default values $rights = new Phprojekt_Item_Rights(); $rights->saveDefaultRights($this->id); return true; } } else { return parent::save(); } }
/** * Try to receive a tree/subtree from the database using the * active record object to get the name of the tree table. * If the requested id is not set using the constructor this method * usually fails throwing an exception. * * @param Phprojekt_Filter_Interface $filter A filter to chain. * * @throws Phprojekt_Tree_Node_Exception If no id was requested (see constructor) * * @return Phprojekt_Tree_Node_Database An instance of Phprojekt_Tree_Node_Database. */ public function setup(Phprojekt_Filter_Abstract $filter = null) { // @todo: fix this, must be possible with requestid === null if (null === $this->_requestedId) { throw new Phprojekt_Tree_Node_Exception('You have to set a requested treeid in the constructor'); } $cache = Phprojekt::getInstance()->getCache(); if ($this->_requestedId == 0) { return $this; } else { if ($this->_requestedId > 1) { if (!($object = $cache->load(self::CACHE_NAME))) { $tree = new Phprojekt_Tree_Node_Database($this->_activeRecord, 1); $object = $tree->setup(); } $tree = $object->getNodeById($this->_requestedId); if (null === $tree) { throw new Phprojekt_Tree_Node_Exception('Requested node not found'); } $tree->_parentNode = null; return $this->applyRights($tree); } else { if (!($object = $cache->load(self::CACHE_NAME))) { $database = $this->getActiveRecord()->getAdapter(); $table = $this->getActiveRecord()->getTableName(); $select = $database->select(); $select->from($table, 'path')->where(sprintf('id = %d', (int) $this->_requestedId))->limit(1); if (null !== $filter) { $filter->filter($select, $this->getActiveRecord()->getAdapter()); } $rootPath = $database->fetchOne($select); if (null === $rootPath) { throw new Phprojekt_Tree_Node_Exception('Requested node not found'); } // Get all the projects $where = sprintf("(%s OR id = %d)", $database->quoteInto("path LIKE ?", $rootPath . '%'), (int) $this->id); $select = $database->select(); $select->from($table)->where($where)->order('path'); $treeData = $select->query()->fetchAll(Zend_Db::FETCH_CLASS); foreach ($treeData as $index => $record) { foreach ($record as $key => $value) { $newKey = Phprojekt_ActiveRecord_Abstract::convertVarFromSql($key); $treeData[$index]->{$newKey} = $value; } } foreach ($treeData as $record) { $node = null; if ($record->id == $this->_requestedId) { $node = $this; $this->_activeRecord = $record; } elseif (array_key_exists($record->projectId, $this->_index)) { $node = new Phprojekt_Tree_Node_Database($record); $this->_index[$record->projectId]->appendNode($node); } if (null !== $node) { $this->_index[$node->id] = $node; } } $object = $this; $cache->save($this, self::CACHE_NAME); // Delete the session for re-calculate the rights $sessionName = 'Phprojekt_Tree_Node_Database-applyRights'; $rightsNamespace = new Zend_Session_Namespace($sessionName); $rightsNamespace->unsetAll(); } } } return $this->applyRights($object); }
/** * Prevent delete modules from the Frontend. * For delete modules use safeDelete. * * @return void */ public function delete() { // Delete all the project-module relations $project = Phprojekt_Loader::getModel('Project', 'ProjectModulePermissions'); $project->deleteModuleRelation($this->id); // Delete all the role-module relations $role = Phprojekt_Loader::getLibraryClass('Phprojekt_Role_RoleModulePermissions'); $role->deleteModuleRelation($this->id); // Delete the items and tags $tag = Phprojekt_Tags::getInstance(); $model = Phprojekt_Loader::getModel($this->name, $this->name); $results = $model->fetchAll(); foreach ($results as $record) { $tag->deleteTagsByItem($this->id, $record->id); $record->delete(); } // Delete Files $this->_deleteFolder(PHPR_CORE_PATH . DIRECTORY_SEPARATOR . $this->name); // Delete module entry parent::delete(); }
/** * Returns an array of all calendar objects for the given uid. * * @param string The uid of the calendar collection * * @return array of Calendar2_Models_Calendar2 All objects belonging to that uid */ public function fetchByUid($uid) { $db = Phprojekt::getInstance()->getDb(); $where = $db->quoteInto('uid = ?', $uid); return Phprojekt_ActiveRecord_Abstract::fetchAll($where); }
/** * Rewrites parent fetchAll, so that only records with read access are shown. * * @param string|array $where Where clause. * @param string|array $order Order by. * @param string|array $count Limit query. * @param string|array $offset Query offset. * @param string $select The comma-separated columns of the joined columns. * @param string $join The join statements. * * @return Zend_Db_Table_Rowset The rowset with the results. */ public function fetchAll($where = null, $order = null, $count = null, $offset = null, $select = null, $join = null) { // Only fetch records with read access $join .= sprintf(' INNER JOIN item_rights ON (item_rights.item_id = %s AND item_rights.module_id = %d AND item_rights.user_id = %d) ', $this->getAdapter()->quoteIdentifier($this->getTableName() . '.id'), Phprojekt_Module::getId($this->getModelName()), Phprojekt_Auth::getUserId()); // Set where if (null !== $where) { $where .= ' AND '; } $where .= ' (' . sprintf('(%s.owner_id = %d OR %s.owner_id IS NULL)', $this->getTableName(), Phprojekt_Auth::getUserId(), $this->getTableName()); $where .= ' OR (item_rights.access > 0)) '; return parent::fetchAll($where, $order, $count, $offset, $select, $join); }
/** * Convert the rule and value into a real where clause. * * @param string $field Field for filter. * @param string $identifier Converted field for filter. * @param string $rule Rule for apply the filter. * @param string $keyword Value used for filter. * * @return string Where clause. */ private function _convertRule($field, $identifier, $rule, $keyword) { // Sanitize values if ($this->_info['metadata'][$identifier]['DATA_TYPE'] == 'time') { // Moving the value to UTC $identifier = $this->_record->getTableName() . '.' . $identifier; $identifier = Phprojekt::getInstance()->getDb()->quoteIdentifier($identifier); $value = Cleaner::sanitize('time', $keyword); $k = date("H:i:s", Phprojekt_Converter_Time::userToUtc($value)); //$identifier = 'TIME(' . $identifier . ')'; } else { if ($this->_info['metadata'][$identifier]['DATA_TYPE'] == 'datetime') { $identifier = $this->_record->getTableName() . '.' . $identifier; $identifier = Phprojekt::getInstance()->getDb()->quoteIdentifier($identifier); if (strstr($keyword, '-')) { // Use it as date $k = Cleaner::sanitize('date', $keyword); $identifier = 'DATE(' . $identifier . ')'; } else { if (strstr($keyword, ':')) { // Use it as time $value = Cleaner::sanitize('time', $keyword); $k = date("H:i:s", Phprojekt_Converter_Time::userToUtc($value)); $identifier = 'TIME(' . $identifier . ')'; } else { // Use it as datetime $value = Cleaner::sanitize('timestamp', $keyword); $k = date("Y-m-d H:i:s", Phprojekt_Converter_Time::userToUtc($value)); } } } else { $keyword = mb_strtolower($keyword, 'UTF-8'); $k = $keyword; $identifier = $this->_record->getTableName() . '.' . $identifier; $identifier = Phprojekt::getInstance()->getDb()->quoteIdentifier($identifier); } } switch ($rule) { case 'equal': $w = $identifier . ' = ? '; break; case 'notEqual': $w = $identifier . ' != ? '; break; case 'major': $w = $identifier . ' > ? '; break; case 'majorEqual': $w = $identifier . ' >= ? '; break; case 'minor': $w = $identifier . ' < ? '; break; case 'minorEqual': $w = $identifier . ' <= ? '; break; case 'begins': $w = $identifier . ' LIKE ? '; $k = $keyword . '%'; break; case 'ends': $w = $identifier . ' LIKE ? '; $k = '%' . $keyword; break; case 'notLike': $w = $identifier . ' NOT LIKE ? '; $k = '%' . $keyword . '%'; break; case 'like': default: $w = $identifier . ' LIKE ? '; $k = '%' . $keyword . '%'; } return Phprojekt::getInstance()->getDb()->quoteInto($w, $k); }
/** * Validates a value using the database type of the field. * * @param Phprojekt_Model_Interface $class Model object. * @param string $varname Name of the field. * @param mix $value Value to validate. * * @return boolean True for valid. */ public function validateValue(Phprojekt_Model_Interface $class, $varname, $value) { $info = $class->info(); $varForInfo = Phprojekt_ActiveRecord_Abstract::convertVarToSql($varname); $valid = true; if (isset($info['metadata'][$varForInfo]) && !empty($value)) { $type = $info['metadata'][$varForInfo]['DATA_TYPE']; switch ($type) { case 'int': $valid = Cleaner::validate('integer', $value, false); break; case 'float': $valid = Cleaner::validate('float', $value, false); break; case 'date': $valid = Cleaner::validate('date', $value, false); break; case 'time': // $valid = Cleaner::validate('timestamp', $value, false); break; case 'timestamp': case 'datetime': $valid = Cleaner::validate('timestamp', $value, false); break; default: $valid = Cleaner::validate('string', $value, true); break; } } return $valid !== false; }
/** * Apply rules for tableField. * * @param string $value Name of the field in the table. * * @return string Converted name. */ public static function convertTableField($value) { return Phprojekt_ActiveRecord_Abstract::convertVarToSql($value); }
/** * Delete a role and all his relations. * It prevents deletion of role 1 -admin role-. * * @return void */ public function delete() { if ($this->id > 1) { parent::delete(); } }
/** * Extencion of the ActiveRecord save adding default permissions. * * @return boolean True for a sucessful save. */ public function save() { // Reset users by project cache $activeRecord = Phprojekt_Loader::getModel('Project', 'Project'); $tree = new Phprojekt_Tree_Node_Database($activeRecord, 1); $tree = $tree->setup(); foreach ($tree as $node) { $sessionName = 'Phprojekt_User_User-getAllowedUsers' . '-' . (int) $node->id; $namespace = new Zend_Session_Namespace($sessionName); if (isset($namespace->users)) { $namespace->unsetAll(); } } if ($this->id == 0) { if (parent::save()) { // adding default values $rights = Phprojekt_Loader::getLibraryClass('Phprojekt_Item_Rights'); $rights->saveDefaultRights($this->id); return true; } } else { return parent::save(); } }
/** * Define the clone function for prevent the same point to same object. * * @return void */ public function __clone() { parent::__clone(); $this->_informationManager = Phprojekt_Loader::getLibraryClass('Phprojekt_Groups_Information'); }
/** * Delete only the own records * * @return boolean */ public function delete() { if ($this->ownerId == Phprojekt_Auth::getUserId()) { return parent::delete(); } else { return false; } }
/** * Prevent delete modules from the Frontend. * For delete modules use safeDelete. * * @return void */ public function delete() { // Delete all the project-module relations $project = new Project_Models_ProjectModulePermissions(); $project->deleteModuleRelation($this->id); // Delete all the role-module relations $role = new Phprojekt_Role_RoleModulePermissions(); $role->deleteModuleRelation($this->id); // Delete the items and tags $tag = new Phprojekt_Tags(); $model = Phprojekt_Loader::getModel($this->name, $this->name); if ($model instanceof Phprojekt_ActiveRecord_Abstract) { $results = $model->fetchAll(); if (is_array($results)) { foreach ($results as $record) { $tag->deleteTagsForModuleItem($this->id, $record->id); // @todo: Improve the delete routine for modules with a lot of entries. $record->delete(); } } } // Delete Files $this->_deleteFolder(PHPR_USER_CORE_PATH . $this->name); // Delete module entry parent::delete(); }
/** * Return all the events for all the users selected in a date. * The function use the ActiveRecord fetchAll for skip the itemRights restrictions. * * @param string $usersId User IDs comma separated. * @param string $date Date for search. * @param integer $count Count for the fetchall. * @param integer $offset Offset for the fetchall. * * @return array Array of Calendar_Models_Calendar. */ public function getUserSelectionRecords($usersId, $date, $count, $offset) { $db = Phprojekt::getInstance()->getDb(); $date = $db->quote($date); $records = array(); if (count($usersId) > 0) { $where = sprintf('participant_id IN (%s) AND DATE(start_datetime) <= %s AND DATE(end_datetime) >= %s', implode(", ", $usersId), $date, $date); $records = Phprojekt_ActiveRecord_Abstract::fetchAll($where, null, $count, $offset); // Hide the title, place and note from the private events $userId = Phprojekt_Auth::getUserId(); foreach ($records as $key => $record) { if ($record->visibility == 1 && $record->participantId != $userId) { $record->title = "-"; $record->notes = "-"; $record->place = "-"; } } } return $records; }
/** * Saves a frontend message to the database using the abstract record pattern. * * Since the actor id is allways the user who calls this method, the actor_id will be set here. * * @return boolean True on a sucessful save. */ public function saveFrontendMessage() { $return = ''; $this->actorId = (int) Phprojekt_Auth::getUserId(); if (false === is_array($this->recipientId)) { $return = parent::save(); } else { $recipient = $this->recipientId; foreach ($recipient as $id) { $model = clone $this; $model->actorId = $this->actorId; $model->projectId = $this->projectId; $model->itemId = $this->itemId; $model->process = $this->process; $model->validUntil = $this->validUntil; $model->validFrom = $this->validFrom; $model->moduleId = $this->moduleId; $model->description = $this->description; $model->details = $this->details; $model->recipientId = $id; $model->itemName = $this->itemName; $return = $model->save(); } } return $return; }
/** * Make a where clause. * * @param string $field Field for filter. * @param string $rule Rule for apply the filter. * @param string $value Value used for filter. * @param string $operator AND/OR operator for concatenate the where clause. * * @return void */ public function addFilter($field, $rule, $value, $operator = 'AND') { $identifier = Phprojekt_ActiveRecord_Abstract::convertVarToSql($field); if (in_array($identifier, $this->_cols)) { $rule = $this->_convertRule($field, $identifier, $rule, $value); if (null !== $this->_userWhere) { $this->_userWhere .= $operator . " "; } $this->_userWhere .= sprintf('(%s) ', $rule); } }
/** * Get all the string values from the Object. * * Allow only text field (varchar, text, tinytext and longtext). * * @param Phprojekt_Item_Abstract $object The item object. * * @return array Array with allowed values. */ private function _getObjectDataToIndex($object) { $allow = array(); $allow[] = 'varchar'; $allow[] = 'text'; $allow[] = 'tinytext'; $allow[] = 'longtext'; $data = array(); $metaData = $object->_metadata; foreach ($metaData as $field => $fieldInfo) { if (in_array($fieldInfo['DATA_TYPE'], $allow)) { $field = Phprojekt_ActiveRecord_Abstract::convertVarFromSql($field); $data[$field] = $object->{$field}; } } return $data; }
/** * Extension of save() for don't save the search strings. * Only allow save if the contact is public or the ownerId is the current user. * * @return void */ public function save() { $result = true; if (!$this->private || $this->private && $this->ownerId == Phprojekt_Auth::getUserId()) { if ($this->id > 0) { $this->_history->saveFields($this, 'edit'); $result = Phprojekt_ActiveRecord_Abstract::save(); } else { $result = Phprojekt_ActiveRecord_Abstract::save(); $this->_history->saveFields($this, 'add'); } } return $result; }
/** * Override count function to account for rights. * * @param string $where A where clause to count a subset of the results. * * @return integer Count of results. */ public function count($where = null) { if (Phprojekt_Auth::isAdminUser()) { return parent::count($where); } $db = Phprojekt::getInstance()->getDb(); $rawTable = $this->getTableName(); $table = $db->quoteIdentifier($rawTable); $select = $db->select()->from($rawTable, array('COUNT(*)')); if (!is_null($where)) { $select->where($where); } $select->join(array('ir' => 'item_rights'), "ir.item_id = {$table}.id", array())->where('ir.module_id = :thisModule')->where('ir.user_id = :effectiveUser')->where("{$table}.owner_id = :effectiveUser OR (ir.access & :right) = :right")->bind(array(':thisModule' => Phprojekt_Module::getId($this->getModelName()), ':effectiveUser' => Phprojekt_Auth_Proxy::getEffectiveUserId(), ':right' => Phprojekt_Acl::READ)); return $select->query()->fetchColumn(); }
/** * Returns the number of the models of the given type in this subtree. * * @param $model The activeRecord module used to get the data. * @param $where The clause to determine matching objects. Optional. */ public function getRecordsCount(Phprojekt_ActiveRecord_Abstract $model, $where = null) { $projectIds = array_keys($this->_index); if (empty($projectIds)) { return 0; } if (!is_null($where)) { $where .= ' AND '; } $where .= $model->getAdapter()->quoteInto('project_id IN (?)', $projectIds); return $model->count($where); }