Array('subitem' => 'add|edit'), ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * Initializes new relation * * @param kEvent $event */ function OnNew(&$event) { parent::OnNew($event); $object =& $event->getObject(); /* @var $object kDBItem */ $table_info = $object->getLinkedInfo(); $object->SetDBField('SourceId', $table_info['ParentId']); $source_itemtype = $this->Application->getUnitOption($table_info['ParentPrefix'], 'ItemType'); $object->SetDBField('SourceType', $source_itemtype); $object->SetDBField('TargetId', $this->Application->GetVar('target_id')); $object->SetDBField('TargetType', $this->Application->GetVar('target_type')); $this->OnAfterItemLoad($event); } /** * Add new relation * * @param kEvent $event */ function OnProcessSelected(&$event) { $dst_field = $this->Application->RecallVar('dst_field'); if ( $dst_field == 'TargetId' ) { // prepare target_id & target_type $object =& $event->getObject(Array ('skip_autoload' => true)); $target_id = 0; $target_prefix = false; $selected_ids = $this->Application->GetVar('selected_ids'); foreach ($selected_ids as $selected_prefix => $target_id) { if ( $target_id > 0 ) { $target_prefix = $selected_prefix; break; } } if ( !$target_prefix ) { $event->SetRedirectParam('opener', 'u'); return; } $sql = 'SELECT ResourceId FROM ' . $this->Application->getUnitOption($target_prefix, 'TableName') . ' WHERE ' . $this->Application->getUnitOption($target_prefix, 'IDField') . ' IN (' . $target_id . ')'; $target_id = $this->Conn->GetOne($sql); $target_type = $this->Application->getUnitOption($target_prefix, 'ItemType'); // don't add same relation twice $table_info = $object->getLinkedInfo(); $sql = 'SELECT TargetId FROM ' . $object->TableName . ' WHERE (SourceId = ' . $table_info['ParentId'] . ') AND (TargetId = ' . $target_id . ')'; $duplicate_relation = $this->Conn->GetOne($sql) == $target_id; $event->SetRedirectParam('opener', 'u'); if ( !$duplicate_relation ) { // place correct template in opener stack $source_prefix = $this->Application->getUnitOption($event->Prefix, 'ParentPrefix'); $template = $this->Application->getUnitOption($source_prefix, 'AdminTemplatePath') . '/relations_edit'; $redirect_params = Array ($event->Prefix . '_event' => 'OnNew', 'target_id' => $target_id, 'm_opener' => 's', 'target_type' => $target_type); $this->Application->EventManager->openerStackPush($template, $redirect_params, 'all,' . $event->Prefix); } } else { $event->SetRedirectParam('opener', 'u'); } } /** * Set ItemName & ItemType virtual fields based on loaded item data * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemLoad(&$event) { parent::OnAfterItemLoad($event); $object =& $event->getObject(); /* @var $object kDBItem */ $sql = 'SELECT Prefix FROM ' . TABLE_PREFIX . 'ItemTypes WHERE ItemType = ' . $object->GetDBField('TargetType'); $target_prefix = $this->Conn->GetOne($sql); $title_field = $this->getTitleField($target_prefix); $title_phrase = $this->Application->getUnitOption($target_prefix, 'TitlePhrase'); $sql = 'SELECT ' . $title_field . ' FROM ' . $this->Application->getUnitOption($target_prefix, 'TableName') . ' WHERE ResourceId = ' . $object->GetDBField('TargetId'); $object->SetDBField('ItemName', $this->Conn->GetOne($sql)); $object->SetDBField('ItemType', $this->Application->Phrase($title_phrase)); } /** * Creates needed sql query to load list, * if no query is defined in config for * special requested, then use default * query * * @param kEvent $event * @access protected */ function ListPrepareQuery(&$event) { return $this->BaseQuery($event, 'ListSQLs'); } /** * Creates needed sql query to load item, * if no query is defined in config for * special requested, then use default * query * * @param kEvent $event * @access protected */ function ItemPrepareQuery(&$event) { return $this->BaseQuery($event, 'ItemSQLs'); } /** * Get item name & type based on relation type & modules installed * * @param kEvent $event * @param string $sql_field */ function BaseQuery(&$event, $sql_field) { $sqls = $this->Application->getUnitOption($event->Prefix,$sql_field); $sql = isset($sqls[$event->Special]) ? $sqls[$event->Special] : $sqls['']; $configs = $this->extractModulesInfo(); // 2. build sql based on information queried $sql_templates['ItemName'] = 'IFNULL(%s.%s,\' \')'; $sql_templates['TableJoin'] = 'LEFT JOIN %1$s ON %1$s.ResourceId = rel.TargetId'; $sql_templates['TargetName'] = 'IF(rel.TargetType = %s, \'%s\', %s)'; $sql_parts = Array(); $sql_parts['TargetName'] = "''"; foreach ($configs as $prefix => $config_data) { $title_field = $this->getTitleField($prefix); $sql_parts['ItemName'][] = sprintf($sql_templates['ItemName'], $config_data['TableName'], $title_field); $sql_parts['TableJoin'][] = sprintf($sql_templates['TableJoin'], $config_data['TableName']); $sql_parts['TargetName'] = sprintf( $sql_templates['TargetName'], $config_data['ItemType'], '!'.$config_data['TitlePhrase'].'!', $sql_parts['TargetName']); $sql_parts['TargetName'] = str_replace('rel','%1$s',$sql_parts['TargetName']); } $object =& $event->getObject(); $vars = Array('#ITEM_NAMES#', '#ITEM_TYPES#'); $replacements = Array( implode(', ',$sql_parts['ItemName']), $sql_parts['TargetName'] ); $calculated_fields = $object->getCalculatedFields(); foreach ($calculated_fields as $field_name => $field_expression) { $calculated_fields[$field_name] = str_replace($vars, $replacements, $field_expression); } $object->setCalculatedFields($calculated_fields); $sql = str_replace('#ITEM_JOIN#', implode(' ',$sql_parts['TableJoin']), $sql); $sql = str_replace('rel.','%1$s.',$sql); return $sql; } /** * Convert TitleField field of kMultiLanguage formatter used for it * * @param string $prefix * @return string */ function getTitleField($prefix) { $lang_prefix = 'l'.$this->Application->GetVar('m_lang').'_'; $title_field = $this->Application->getUnitOption($prefix, 'TitleField'); $field_options = $this->Application->getUnitOption($prefix.'.'.$title_field, 'Fields'); $formatter_class = isset($field_options['formatter']) ? $field_options['formatter'] : ''; if ($formatter_class == 'kMultiLanguage' && !isset($field_options['master_field'])) { $title_field = $lang_prefix.$title_field; } return $title_field; } /** * Get configs from modules installed * * @return Array * @access private */ function extractModulesInfo() { // get installed modules & their config info // maybe we should leave only prefixes, that have "view" permission $configs = Array(); foreach ($this->Application->ModuleInfo as $module_name => $module_data) { $prefix = $module_data['Var']; if ($prefix == 'm') { $prefix = 'c'; } if (!$this->Application->prefixRegistred($prefix)) continue; $configs[$prefix] = $this->Application->getUnitOptions($prefix); if($configs[$prefix] === false) unset($configs[$prefix]); if(!isset($configs[$prefix]['CatalogItem']) || !$configs[$prefix]['CatalogItem']) unset($configs[$prefix]); } return $configs; } /** * Deletes relations to hooked item from other items * * @param kEvent $event */ function OnDeleteForeignRelations(&$event) { $main_object =& $event->MasterEvent->getObject(); $resource_id = $main_object->GetDBField('ResourceId'); $table = $this->Application->getUnitOption($event->Prefix,'TableName'); $sql = 'DELETE FROM '.$table.' WHERE TargetId = '.$resource_id; $this->Conn->Query($sql); } }