Index: branches/RC/core/units/general/cat_dbitem.php =================================================================== diff -u -N --- branches/RC/core/units/general/cat_dbitem.php (revision 11892) +++ branches/RC/core/units/general/cat_dbitem.php (revision 0) @@ -1,598 +0,0 @@ -CategoryPath = Array(); - } - - /** - * Set's prefix and special - * - * @param string $prefix - * @param string $special - * @access public - */ - function Init($prefix, $special, $event_params = null) - { - parent::Init($prefix, $special, $event_params); - $this->usePendingEditing = $this->Application->getUnitOption($this->Prefix, 'UsePendingEditing'); - } - - function Create($force_id = false, $system_create = false) - { - // TODO: move to OnBeforeItemCreate method - if ($this->Validate()) { - // TODO: such approach will not respect changes from OnBeforeItemCreate event - $this->SetDBField('ResourceId', $this->Application->NextResourceId()); - } - - $this->SetDBField('Modified_date', adodb_mktime() ); - $this->SetDBField('Modified_time', adodb_mktime() ); - - if ($this->mode != 't' && !$this->Application->IsAdmin()) { - $owner_field = $this->Application->getUnitOption($this->Prefix, 'OwnerField'); - if (!$owner_field) { - $owner_field = 'CreatedById'; - } - $this->SetDBField($owner_field, $this->Application->RecallVar('user_id')); - } - - if ($this->useFilenames) { - $this->checkFilename(); - $this->generateFilename(); - } - - $ret = parent::Create($force_id, $system_create); - - if ($ret) { - // TODO: move to OnAfterItemCreate method - $this->assignPrimaryCategory(); - } - return $ret; - } - - function assignPrimaryCategory() - { - $primary_category = $this->GetDBField('CategoryId') > 0 ? $this->GetDBField('CategoryId') : $this->Application->GetVar('m_cat_id'); - $this->assignToCategory($primary_category, true); - } - - function Update($id=null, $system_update=false) - { - $this->VirtualFields['ResourceId'] = Array(); - $this->SetDBField('Modified', adodb_mktime() ); - $this->UpdateFormattersSubFields(array('Modified')); - $this->SetDBField('ModifiedById', $this->Application->RecallVar('user_id')); - - if ($this->useFilenames) { - $this->checkFilename(); - $this->generateFilename(); - } - - $ret = parent::Update($id, $system_update); - - if ($ret) { - $filename = $this->useFilenames ? $this->GetDBField('Filename') : ''; - $sql = 'UPDATE '.$this->CategoryItemsTable().' - SET Filename = '.$this->Conn->qstr($filename).' - WHERE ItemResourceId = '.$this->GetDBField('ResourceId'); - $this->Conn->Query($sql); - } - - unset($this->VirtualFields['ResourceId']); - return $ret; - } - - /** - * Returns CategoryItems table based on current item mode (temp/live) - * - * @return string - */ - function CategoryItemsTable() - { - $table = TABLE_PREFIX.'CategoryItems'; - if ($this->Application->IsTempTable($this->TableName)) { - $table = $this->Application->GetTempName($table, 'prefix:'.$this->Prefix); - } - - return $table; - } - - - function checkFilename() - { - if( !$this->GetDBField('AutomaticFilename') ) - { - $filename = $this->GetDBField('Filename'); - $this->SetDBField('Filename', $this->stripDisallowed($filename) ); - } - } - - function Copy($cat_id=null) - { - if (!isset($cat_id)) $cat_id = $this->Application->GetVar('m_cat_id'); - $this->NameCopy($cat_id); - return $this->Create($cat_id); - } - - function NameCopy($master=null, $foreign_key=null) - { - $title_field = $this->Application->getUnitOption($this->Prefix, 'TitleField'); - if (!$title_field) return; - - $new_name = $this->GetDBField($title_field); - $cat_id = $this->Application->GetVar('m_cat_id'); - $original_checked = false; - do { - if ( preg_match('/Copy ([0-9]*) *of (.*)/', $new_name, $regs) ) { - $new_name = 'Copy '.( (int)$regs[1] + 1 ).' of '.$regs[2]; - } - elseif ($original_checked) { - $new_name = 'Copy of '.$new_name; - } - $query = 'SELECT '.$title_field.' FROM '.$this->TableName.' - LEFT JOIN '.TABLE_PREFIX.'CategoryItems ON - ('.TABLE_PREFIX.'CategoryItems.ItemResourceId = '.$this->TableName.'.ResourceId) - WHERE ('.TABLE_PREFIX.'CategoryItems.CategoryId = '.$cat_id.') AND '. - $title_field.' = '.$this->Conn->qstr($new_name); - $res = $this->Conn->GetOne($query); - $original_checked = true; - } while ($res !== false); - $this->SetDBField($title_field, $new_name); - - // this is needed, because Create will create items in its own CategoryId (if it's set), - // but we need to create it in target Paste category @see{kCatDBItem::Create} and its primary_category detection - $this->SetDBField('CategoryId', $cat_id); - } - - /** - * Changes item primary category to given/current category - * - * @param int $category_id - */ - function MoveToCat($category_id = null) - { -// $this->NameCopy(); - if (!isset($category_id)) { - $category_id = $this->Application->GetVar('m_cat_id'); - } - - $table_name = TABLE_PREFIX . 'CategoryItems'; - if ($this->IsTempTable()) { - $table_name = $this->Application->GetTempName($table_name, 'prefix:' . $this->Prefix); - } - - // check if the item already exists in destination category - $sql = 'SELECT PrimaryCat - FROM ' . $table_name . ' - WHERE (CategoryId = ' . $category_id . ') AND (ItemResourceId = ' . $this->GetDBField('ResourceId') . ')'; - $is_primary = $this->Conn->GetOne($sql); - - // if it's not found is_primary will be FALSE, if it's found but not primary it will be int 0 - $exists = $is_primary !== false; - - if ($exists) { - // if the item already exists in destination category - if ($is_primary) { - // do nothing when we paste to primary - return ; - } - - // if it's not primary - delete it from destination category, as we will move it from current primary below - $sql = 'DELETE FROM ' . $table_name . ' - WHERE (CategoryId = ' . $category_id . ') AND (ItemResourceId = ' . $this->GetDBField('ResourceId') . ')'; - $this->Conn->Query($sql); - } - - // change category id in existing primary category record - $sql = 'UPDATE ' . $table_name . ' - SET CategoryId = ' . $category_id . ' - WHERE (ItemResourceId = ' . $this->GetDBField('ResourceId') . ') AND (PrimaryCat = 1)'; - $this->Conn->Query($sql); - - $this->Update(); - } - - /** - * When item is deleted, then also delete it from all categories - * - * @param int $id - * @return bool - */ - function Delete($id = null) - { - if( isset($id) ) { - $this->setID($id); - } - - $this->Load($this->GetID()); - - $ret = parent::Delete(); - - if ($ret) { - // TODO: move to OnAfterItemDelete method - $query = ' DELETE FROM ' . $this->CategoryItemsTable() . ' - WHERE ItemResourceId = ' . $this->GetDBField('ResourceId'); - $this->Conn->Query($query); - } - - return $ret; - } - - /** - * Deletes item from categories - * - * @param Array $delete_category_ids - * @author Alex - */ - function DeleteFromCategories($delete_category_ids) - { - $id_field = $this->Application->getUnitOption($this->Prefix, 'IDField'); // because item was loaded before by ResourceId - - $ci_table = $this->Application->getUnitOption($this->Prefix.'-ci', 'TableName'); - $resource_id = $this->GetDBField('ResourceId'); - - $item_cats_sql = 'SELECT CategoryId FROM %s WHERE ItemResourceId = %s'; - $delete_category_items_sql = 'DELETE FROM %s WHERE ItemResourceId = %s AND CategoryId IN (%s)'; - - $category_ids = $this->Conn->GetCol( sprintf($item_cats_sql, $ci_table, $resource_id) ); - $cats_left = array_diff($category_ids, $delete_category_ids); - if(!$cats_left) - { - $sql = 'SELECT %s FROM %s WHERE ResourceId = %s'; - $ids = $this->Conn->GetCol( sprintf($sql, $id_field, $this->TableName, $resource_id) ); - - $temp =& $this->Application->recallObject($this->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler'); - $temp->DeleteItems($this->Prefix, $this->Special, $ids); - } - else - { - $this->Conn->Query( sprintf($delete_category_items_sql, $ci_table, $resource_id, implode(',', $delete_category_ids) ) ); - - $sql = 'SELECT CategoryId FROM %s WHERE PrimaryCat = 1 AND ItemResourceId = %s'; - $primary_cat_id = $this->Conn->GetCol( sprintf($sql, $ci_table, $resource_id) ); - if( count($primary_cat_id) == 0 ) - { - $sql = 'UPDATE %s SET PrimaryCat = 1 WHERE (CategoryId = %s) AND (ItemResourceId = %s)'; - $this->Conn->Query( sprintf($sql, $ci_table, reset($cats_left), $resource_id ) ); - } - } - } - - /** - * replace not allowed symbols with "_" chars + remove duplicate "_" chars in result - * - * @param string $string - * @return string - */ - function stripDisallowed($filename) - { - $filenames_helper =& $this->Application->recallObject('FilenamesHelper'); - $table = $this->mode == 't' ? $this->Application->GetTempName(TABLE_PREFIX.'CategoryItems', 'prefix:'.$this->Prefix) : TABLE_PREFIX.'CategoryItems'; - - return $filenames_helper->stripDisallowed($table, 'ItemResourceId', $this->GetDBField('ResourceId'), $filename); - } - - /* commented out because it's called only from stripDisallowed body, which is moved to helper - - function checkAutoFilename($filename) - { - $filenames_helper =& $this->Application->recallObject('FilenamesHelper'); - return $filenames_helper->checkAutoFilename($this->TableName, $this->IDField, $this->GetID(), $filename); - }*/ - - /** - * Generate item's filename based on it's title field value - * - * @return string - */ - function generateFilename() - { - if ( !$this->GetDBField('AutomaticFilename') && $this->GetDBField('Filename') ) return false; - - $title_field = $this->Application->getUnitOption($this->Prefix, 'TitleField'); - if (preg_match('/l([\d]+)_(.*)/', $title_field, $regs)) { - // if title field is multilingual, then use it's name from primary language - $title_field = 'l'.$this->Application->GetDefaultLanguageId().'_'.$regs[2]; - } - $name = $this->stripDisallowed( $this->GetDBField($title_field) ); - - if ( $name != $this->GetDBField('Filename') ) $this->SetDBField('Filename', $name); - } - - /** - * Check if value is set for required field - * - * @param string $field field name - * @param Array $params field options from config - * @return bool - * @access private - */ - function ValidateRequired($field, $params) - { - $res = true; - if (getArrayValue($params, 'required')) { - $res = ( (string) $this->FieldValues[$field] != ''); - } - if (!$res) { - $this->SetError($field, 'required'); - } - return $res; - } - - /** - * Adds item to other category - * - * @param int $category_id - * @param bool $is_primary - */ - function assignToCategory($category_id, $is_primary = false) - { - $table = $this->CategoryItemsTable(); - $key_clause = '(ItemResourceId = '.$this->GetDBField('ResourceId').')'; - - // get all cateories, where item is in - $sql = 'SELECT PrimaryCat, CategoryId FROM '.$table.' WHERE '.$key_clause; - $item_categories = $this->Conn->GetCol($sql, 'CategoryId'); - if (!$item_categories) { - $item_categories = Array(); - $primary_found = false; - } - - // find primary category - foreach ($item_categories as $item_category_id => $primary_found) { - if ($primary_found) { - break; - } - } - - if ($primary_found && ($item_category_id == $category_id) && !$is_primary) { - // want to make primary category as non-primary :( - return true; - } - else if (!$primary_found) { - $is_primary = true; - } - - if ($is_primary && $item_categories) { - // reset primary mark from all other categories - $sql = 'UPDATE '.$table.' SET PrimaryCat = 0 WHERE '.$key_clause; - $this->Conn->Query($sql); - } - - // UPDATE & INSERT instead of REPLACE because CategoryItems table has no primary key defined in database - if (isset($item_categories[$category_id])) { - $sql = 'UPDATE '.$table.' SET PrimaryCat = '.($is_primary ? 1 : 0).' WHERE '.$key_clause.' AND (CategoryId = '.$category_id.')'; - $this->Conn->Query($sql); - } - else { - $fields_hash = Array( - 'CategoryId' => $category_id, - 'ItemResourceId' => $this->GetField('ResourceId'), - 'PrimaryCat' => $is_primary ? 1 : 0, - 'ItemPrefix' => $this->Prefix, - 'Filename' => $this->useFilenames ? $this->GetDBField('Filename') : '', // because some prefixes does not use filenames, - ); - $this->Conn->doInsert($fields_hash, $table); - } - // to ensure filename update after adding to another category - // this is critical since there may be an item with same filename in newly added category! - $this->Update(); - } - - /** - * Removes item from category specified - * - * @param int $category_id - */ - function removeFromCategory($category_id) - { - $sql = 'DELETE FROM '.TABLE_PREFIX.'CategoryItems WHERE (CategoryId = %s) AND (ItemResourceId = %s)'; - $this->Conn->Query( sprintf($sql, $category_id, $this->GetDBField('ResourceId')) ); - } - - /** - * Returns list of columns, that could exist in imported file - * - * @return Array - */ - function getPossibleExportColumns() - { - static $columns = null; - if (!is_array($columns)) { - $columns = array_merge($this->Fields['AvailableColumns']['options'], $this->Fields['ExportColumns']['options']); - } - return $columns; - } - - /** - * Returns item's primary image data - * - * @return Array - */ - function getPrimaryImageData() - { - $sql = 'SELECT * - FROM '.TABLE_PREFIX.'Images - WHERE (ResourceId = '.$this->GetDBField('ResourceId').') AND (DefaultImg = 1)'; - $image_data = $this->Conn->GetRow($sql); - if (!$image_data) { - // 2. no primary image, then get image with name "main" - $sql = 'SELECT * - FROM '.TABLE_PREFIX.'Images - WHERE (ResourceId = '.$this->GetDBField('ResourceId').') AND (Name = "main")'; - $image_data = $this->Conn->GetRow($sql); - } - return $image_data; - } - - function ChangeStatus($new_status) - { - $status_field = array_shift( $this->Application->getUnitOption($this->Prefix,'StatusField') ); - if ($new_status != $this->GetDBField($status_field)) { - // status was changed - $this->sendEmailEvents($new_status); - } - $this->SetDBField($status_field, $new_status); - - return $this->Update(); - } - - function sendEmailEvents($new_status) - { - $perm_prefix = $this->Application->getUnitOption($this->Prefix, 'PermItemPrefix'); - $owner_field = $this->Application->getUnitOption($this->Prefix, 'OwnerField'); - if (!$owner_field) { - $owner_field = 'CreatedById'; - } - - $event_name = $perm_prefix.'.'.($new_status == STATUS_ACTIVE ? 'APPROVE' : 'DENY'); - $this->Application->EmailEventUser($event_name, $this->GetDBField($owner_field)); - } - - /** - * Approves changes made to category item - * - * @return bool - */ - function ApproveChanges() - { - $original_id = $this->GetDBField('OrgId'); - - if (!($this->usePendingEditing && $original_id)) { - // non-pending copy of original link - return $this->ChangeStatus(STATUS_ACTIVE); - } - - if ($this->raiseEvent('OnBeforeDeleteOriginal', null, Array('original_id' => $original_id))) { - // delete original item, because changes made in pending copy (this item) got to be approved in this method - $temp_handler =& $this->Application->recallObject($this->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler'); - $temp_handler->DeleteItems($this->Prefix, $this->Special, Array($original_id)); - - $this->SetDBField('OrgId', 0); - return $this->ChangeStatus(STATUS_ACTIVE); - } - - return false; - } - - /** - * Decline changes made to category item - * - * @return bool - */ - function DeclineChanges() - { - $original_id = $this->GetDBField('OrgId'); - - if (!($this->usePendingEditing && $original_id)) { - // non-pending copy of original link - return $this->ChangeStatus(STATUS_DISABLED); - } - - // delete this item, because changes made in pending copy (this item) will be declined in this method - $temp_handler =& $this->Application->recallObject($this->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler'); - $temp_handler->DeleteItems($this->Prefix, $this->Special, Array($this->GetID())); - - // original item is not changed here, because it is already enabled (thrus pending copy is visible to item's owner or admin with permission) - return true; - } - - function RegisterHit() - { - $already_viewed = $this->Application->RecallVar($this->getPrefixSpecial().'_already_viewed'); - $already_viewed = $already_viewed ? unserialize($already_viewed) : Array (); - - $id = $this->GetID(); - if (!in_array($id, $already_viewed)) { - $property_map = $this->Application->getUnitOption($this->Prefix, 'ItemPropertyMappings'); - if (!$property_map) { - return ; - } - $hits_field = $property_map['ClickField']; - $new_hits = $this->GetDBField($hits_field) + 1; - - $sql = 'SELECT MAX('.$hits_field.') - FROM '.$this->TableName.' - WHERE FLOOR('.$hits_field.') = '.$new_hits; - $max_hits = $this->Conn->GetOne($sql); - if ($max_hits) { - $new_hits = $max_hits + 0.000001; - } - - $fields_hash = Array ( - $hits_field => $new_hits, - ); - $this->Conn->doUpdate($fields_hash, $this->TableName, $this->IDField.' = '.$id); - - array_push($already_viewed, $id); - $this->Application->StoreVar($this->getPrefixSpecial().'_already_viewed', serialize($already_viewed)); - } - } - - /** - * Returns part of SQL WHERE clause identifing the record, ex. id = 25 - * - * @access public - * @param string $method Child class may want to know who called GetKeyClause, Load(), Update(), Delete() send its names as method - * @param Array $keys_hash alternative, then item id, keys hash to load item by - * @return void - * @see kDBItem::Load() - * @see kDBItem::Update() - * @see kDBItem::Delete() - */ - function GetKeyClause($method = null, $keys_hash = null) - { - if ($method == 'load') { - // for item with many categories makes primary to load - $ci_table = TABLE_PREFIX.'CategoryItems'; - if ($this->IsTempTable()) { - $ci_table = $this->Application->GetTempName($ci_table, 'prefix:'.$this->Prefix); - } - $keys_hash = Array( - $this->IDField => $this->ID, - '`'.$ci_table.'`.`PrimaryCat`' => 1, - ); - } - return parent::GetKeyClause($method, $keys_hash); - } - -} - -?> \ No newline at end of file