/** * Logic to set the access level of the Items * * @access public * @return void * @since 1.5 */ function access() { // Check for request forgeries JRequest::checkToken() or jexit('Invalid Token'); $user = JFactory::getUser(); $cid = JRequest::getVar('cid', array(0), 'post', 'array'); $id = (int) $cid[0]; $task = JRequest::getVar('task'); // Decide / Retrieve new access level $accesses = JRequest::getVar('access', array(0), 'post', 'array'); $access = $accesses[$id]; $model = $this->getModel('item'); $canEdit = $model->getItemAccess()->get('access-edit'); // Check if user can edit the item if (!$canEdit) { $msg_noauth = JText::_('FLEXI_CANNOT_CHANGE_ACCLEVEL_ASSETS'); $msg_noauth .= ": " . implode(',', $non_auth_cid) . " - " . JText::_('FLEXI_REASON_NO_PUBLISH_PERMISSION'); } if ($msg_noauth) { JError::raiseNotice(500, $msg_noauth); $this->setRedirect('index.php?option=com_flexicontent&view=items', ''); return; } $model = $this->getModel('items'); if (!$model->saveaccess($id, $access)) { $msg = JText::_('FLEXI_ERROR_SETTING_ITEM_ACCESS_LEVEL'); JError::raiseWarning(500, $msg . " " . $model->getError()); $msg = ''; } else { $cache = FLEXIUtilities::getCache($group = '', 0); $cache->clean('com_flexicontent_items'); $cache->clean('com_flexicontent_filters'); $cache = FLEXIUtilities::getCache($group = '', 1); $cache->clean('com_flexicontent_items'); $cache->clean('com_flexicontent_filters'); } $this->setRedirect('index.php?option=com_flexicontent&view=items'); }
function initialPermission() { $component_name = JRequest::getCmd('option'); $db = JFactory::getDBO(); $asset = JTable::getInstance('asset'); // Create an asset object /*** Component assets ***/ if (!$asset->loadByName($component_name)) { // The assets entry does not exist: We will create initial rules for all component's actions // Get root asset $root = JTable::getInstance('asset'); $root->loadByName('root.1'); // Initialize component asset $asset->name = $component_name; $asset->title = $component_name; $asset->setLocation($root->id, 'last-child'); // father of compontent asset it the root asset // Create initial component rules and set them into the asset $initial_rules = $this->_createComponentRules($component_name); $component_rules = new JAccessRules(json_encode($initial_rules)); $asset->rules = $component_rules->__toString(); // Save the asset into the DB if (!$asset->check() || !$asset->store()) { echo $asset->getError(); $this->setError($asset->getError()); return false; } } else { // The assets entry already exists: We will check if it has exactly the actions specified in component's access.xml file // Get existing DB rules and component's actions from the access.xml file $existing_rules = new JAccessRules($asset->rules); $rules_data = $existing_rules->getData(); $component_actions = JAccess::getActions('com_flexicontent', 'component'); // Find any deleted / added actions ... $db_action_names = array(); foreach ($rules_data as $action_name => $data) { $db_action_names[] = $action_name; } foreach ($component_actions as $action) { $file_action_names[] = $action->name; } $deleted_actions = array_diff($db_action_names, $file_action_names); $added_actions = array_diff($file_action_names, $db_action_names); if (count($deleted_actions) || count($added_actions)) { // We have changes in the component actions // First merge the existing component (db) rules into the initial rules $initial_rules = $this->_createComponentRules($component_name); $component_rules = new JAccessRules(json_encode($initial_rules)); $component_rules->merge($existing_rules); // Second, check if obsolete rules are contained in the existing component (db) rules, if so create a new rules object without the obsolete rules if ($deleted_actions) { $rules_data = $component_rules->getData(); foreach ($deleted_actions as $action_name) { unset($rules_data[$action_name]); } $component_rules = new JAccessRules($rules_data); } // Set asset rules $asset->rules = $component_rules->__toString(); // Save the asset if (!$asset->check() || !$asset->store()) { echo $asset->getError(); $this->setError($asset->getError()); return false; } } } // Load component asset $component_asset = JTable::getInstance('asset'); $component_asset->loadByName($component_name); /*** CATEGORY assets ***/ // Get a list com_content categories that do not have assets (or have wrong asset names) $query = $db->getQuery(true)->select('c.id, c.parent_id, c.title, c.asset_id')->from('#__assets AS se')->join('RIGHT', '#__categories AS c ON se.id=c.asset_id AND se.name=concat("com_content.category.",c.id)')->where('(se.id is NULL OR (c.parent_id=1 AND se.parent_id!=' . (int) $asset->id . ') )')->where('c.extension = ' . $db->quote('com_content'))->order('c.level ASC'); // IMPORTANT create categories asset using increasing depth level, so that get parent assetid will not fail $db->setQuery($query); $results = $db->loadObjectList(); if ($db->getErrorNum()) { echo $db->getErrorMsg(); } // Add an asset to every category that doesnot have one if (count($results) > 0) { foreach ($results as $category) { $parentId = $this->_getAssetParentId(null, $category); $name = "com_content.category.{$category->id}"; // Try to load asset for the current CATEGORY ID $asset_found = $asset->loadByName($name); if (!$asset_found) { if ($category->asset_id) { // asset name not found but category has an asset id set ?, we could delete it here // but it maybe dangerous to do so ... it might be a legitimate asset_id for something else } // Set id to null since we will be creating a new asset on store $asset->id = null; // Set asset rules to empty, (DO NOT set any ACTIONS, just let them inherit ... from parent) $asset->rules = new JAccessRules(); /*if ($parentId == $component_asset->id) { $actions = JAccess::getActions($component_name, 'category'); $rules = json_decode($component_asset->rules); foreach ($actions as $action) { $catrules[$action->name] = $rules->{$action->name}; } $rules = new JAccessRules(json_encode($catrules)); $asset->rules = $rules->__toString(); } else { $parent = JTable::getInstance('asset'); $parent->load($parentId); $asset->rules = $parent->rules; }*/ } else { // do not change (a) the id OR (b) the rules, of the asset } // Initialize appropriate asset properties $asset->name = $name; $asset->title = $category->title; $asset->setLocation($parentId, 'last-child'); // Permissions of categories are inherited by parent category, or from component if no parent category exists // Save the category asset (create or update it) if (!$asset->check() || !$asset->store(false)) { echo $asset->getError(); echo " Problem for asset with id: " . $asset->id; echo " Problem for category with id: " . $category->id . "(" . $category->title . ")"; $this->setError($asset->getError()); return false; } // Assign the asset to the category, if it is not already assigned $query = $db->getQuery(true)->update('#__categories')->set('asset_id = ' . (int) $asset->id)->where('id = ' . (int) $category->id); $db->setQuery($query); if (!$db->query()) { echo JText::sprintf('JLIB_DATABASE_ERROR_STORE_FAILED', get_class($this), $db->getErrorMsg()); $this->setError(JText::sprintf('JLIB_DATABASE_ERROR_STORE_FAILED', get_class($this), $db->getErrorMsg())); return false; } } } /*** ITEM assets ***/ /* // Get a list com_content items that do not have assets (or have wrong asset names) $query = $db->getQuery(true) ->select('c.id, c.catid as parent_id, c.title, c.asset_id') ->from('#__assets AS se')->join('RIGHT', '#__content AS c ON se.id=c.asset_id AND se.name=concat("com_content.article.",c.id)') ->where('se.id is NULL');//->where('c.extension = ' . $db->quote('com_content')); $db->setQuery($query); $results = $db->loadObjectList(); if ($db->getErrorNum()) echo $db->getErrorMsg(); // Add an asset to every item that doesnot have one if(count($results)>0) { foreach($results as $item) { $parentId = $this->_getAssetParentId(null, $item); $name = "com_content.article.{$item->id}"; // Try to load asset for the current CATEGORY ID $asset_found = $asset->loadByName($name); if ( !$asset_found ) { if ($item->asset_id) { // asset name not found but item has an asset id set ?, we could delete it here // but it maybe dangerous to do so ... it might be a legitimate asset_id for something else } // Set id to null since we will be creating a new asset on store $asset->id = null; // Set asset rules to empty, (DO NOT set any ACTIONS, just let them inherit ... from parent) $asset->rules = new JAccessRules(); //if ($parentId == $component_asset->id) { // $actions = JAccess::getActions($component_name, 'article'); // $rules = json_decode($component_asset->rules); // foreach ($actions as $action) { // $catrules[$action->name] = $rules->{$action->name}; // } // $rules = new JAccessRules(json_encode($catrules)); // $asset->rules = $rules->__toString(); //} else { // $parent = JTable::getInstance('asset'); // $parent->load($parentId); // $asset->rules = $parent->rules; //} } else { // do not change (a) the id OR (b) the rules, of the asset } // Initialize appropriate asset properties $asset->name = $name; $asset->title = $item->title; $asset->setLocation($parentId, 'last-child'); // Permissions of items are inherited from their main category // Save the item asset (create or update it) if (!$asset->check() || !$asset->store(false)) { echo $asset->getError(); $this->setError($asset->getError()); return false; } // Assign the asset to the item, if it is not already assigned $query = $db->getQuery(true) ->update('#__content') ->set('asset_id = ' . (int)$asset->id) ->where('id = ' . (int)$item->id); $db->setQuery($query); if (!$db->query()) { echo JText::sprintf('JLIB_DATABASE_ERROR_STORE_FAILED', get_class($this), $db->getErrorMsg()); $this->setError(JText::sprintf('JLIB_DATABASE_ERROR_STORE_FAILED', get_class($this), $db->getErrorMsg())); return false; } } } */ /*** FLEXIcontent FIELDS assets ***/ // Get a list flexicontent fields that do not have assets $query = $db->getQuery(true)->select('ff.id, ff.name, ff.asset_id')->from('#__assets AS se')->join('RIGHT', '#__flexicontent_fields AS ff ON se.id=ff.asset_id AND se.name=concat("com_flexicontent.field.",ff.id)')->where('se.id is NULL'); $db->setQuery($query); $results = $db->loadObjectList(); if ($db->getErrorNum()) { echo $db->getErrorMsg(); } // Add an asset to every field that doesnot have one if (count($results) > 0) { foreach ($results as $field) { $name = "com_flexicontent.field.{$field->id}"; // Test if an asset for the current FIELD ID already exists and load it instead of creating a new asset if (!$asset->loadByName($name)) { if ($field->asset_id) { // asset name not found but field has an asset id set ?, we could delete it here // but it maybe dangerous to do so ... it might be a legitimate asset_id for something else } // Initialize field asset $asset->id = null; $asset->name = $name; $asset->title = $field->name; $asset->setLocation($component_asset->id, 'last-child'); // Permissions of fields are directly inheritted by component // Set asset rules to empty, (DO NOT set any ACTIONS, just let them inherit ... from parent) $asset->rules = new JAccessRules(); /* $actions = JAccess::getActions($component_name, 'field'); $rules = json_decode($component_asset->rules); foreach ($actions as $action) { $fieldrules[$action->name] = $rules->{$action->name}; } $rules = new JAccessRules(json_encode($fieldrules)); $asset->rules = $rules->__toString(); */ // Save the asset if (!$asset->check() || !$asset->store(false)) { echo $asset->getError(); $this->setError($asset->getError()); return false; } } // Assign the asset to the field $query = $db->getQuery(true)->update('#__flexicontent_fields')->set('asset_id = ' . (int) $asset->id)->where('id = ' . (int) $field->id); $db->setQuery($query); if (!$db->query()) { echo JText::sprintf('JLIB_DATABASE_ERROR_STORE_FAILED', get_class($this), $db->getErrorMsg()); $this->setError(JText::sprintf('JLIB_DATABASE_ERROR_STORE_FAILED', get_class($this), $db->getErrorMsg())); return false; } } } /*** FLEXIcontent TYPES assets ***/ // Get a list flexicontent types that do not have assets $query = $db->getQuery(true)->select('ff.id, ff.name, ff.asset_id')->from('#__assets AS se')->join('RIGHT', '#__flexicontent_types AS ff ON se.id=ff.asset_id AND se.name=concat("com_flexicontent.type.",ff.id)')->where('se.id is NULL'); $db->setQuery($query); $results = $db->loadObjectList(); if ($db->getErrorNum()) { echo $db->getErrorMsg(); } // Add an asset to every type that doesnot have one if (count($results) > 0) { foreach ($results as $type) { $name = "com_flexicontent.type.{$type->id}"; // Test if an asset for the current TYPE ID already exists and load it instead of creating a new asset if (!$asset->loadByName($name)) { if ($type->asset_id) { // asset name not found but type has an asset id set ?, we could delete it here // but it maybe dangerous to do so ... it might be a legitimate asset_id for something else } // Initialize type asset $asset->id = null; $asset->name = $name; $asset->title = $type->name; $asset->setLocation($component_asset->id, 'last-child'); // Permissions of types are directly inheritted by component // Set asset rules to empty, (DO NOT set any ACTIONS, just let them inherit ... from parent) $asset->rules = new JAccessRules(); /* $actions = JAccess::getActions($component_name, 'type'); $rules = json_decode($component_asset->rules); foreach ($actions as $action) { $typerules[$action->name] = $rules->{$action->name}; } $rules = new JAccessRules(json_encode($typerules)); $asset->rules = $rules->__toString(); */ // Save the asset if (!$asset->check() || !$asset->store(false)) { echo $asset->getError(); $this->setError($asset->getError()); return false; } } // Assign the asset to the type $query = $db->getQuery(true)->update('#__flexicontent_types')->set('asset_id = ' . (int) $asset->id)->where('id = ' . (int) $type->id); $db->setQuery($query); if (!$db->query()) { echo JText::sprintf('JLIB_DATABASE_ERROR_STORE_FAILED', get_class($this), $db->getErrorMsg()); $this->setError(JText::sprintf('JLIB_DATABASE_ERROR_STORE_FAILED', get_class($this), $db->getErrorMsg())); return false; } } } // Clear cache so that per user permissions objects are recalculated $cache = FLEXIUtilities::getCache($group = '', 0); $cache->clean('com_flexicontent_cats'); $cache = FLEXIUtilities::getCache($group = '', 1); $cache->clean('com_flexicontent_cats'); return true; }
/** * Logic to change the state of an item * * @access public * @return void * @since 1.0 */ static function setitemstate($controller_obj) { $id = JRequest::getInt('id', 0); JRequest::setVar('cid', $id); $app = JFactory::getApplication(); $modelname = $app->isAdmin() ? 'item' : FLEXI_ITEMVIEW; $model = $controller_obj->getModel($modelname); $user = JFactory::getUser(); $state = JRequest::getVar('state', 0); // Get owner and other item data $db = JFactory::getDBO(); $q = "SELECT id, created_by, catid FROM #__content WHERE id =" . $id; $db->setQuery($q); $item = $db->loadObject(); // Determine priveleges of the current user on the given item $asset = 'com_content.article.' . $item->id; $has_edit_state = $user->authorise('core.edit.state', $asset) || $user->authorise('core.edit.state.own', $asset) && $item->created_by == $user->get('id'); $has_delete = $user->authorise('core.delete', $asset) || $user->authorise('core.delete.own', $asset) && $item->created_by == $user->get('id'); // ... $permission = FlexicontentHelperPerm::getPerm(); $has_archive = $permission->CanArchives; $has_edit_state = $has_edit_state && in_array($state, array(0, 1, -3, -4, -5)); $has_delete = $has_delete && $state == -2; $has_archive = $has_archive && $state == 2; // check if user can edit.state of the item $access_msg = ''; if (!$has_edit_state && !$has_delete && !$has_archive) { //echo JText::_( 'FLEXI_NO_ACCESS_CHANGE_STATE' ); echo JText::_('FLEXI_DENIED'); // must a few words return; } else { if (!$model->setitemstate($id, $state)) { $msg = JText::_('FLEXI_ERROR_SETTING_THE_ITEM_STATE'); echo $msg . ": " . $model->getError(); return; } } // Clean cache $cache = FLEXIUtilities::getCache($group = '', 0); $cache->clean('com_flexicontent_items'); $cache->clean('com_flexicontent_filters'); $cache = FLEXIUtilities::getCache($group = '', 1); $cache->clean('com_flexicontent_items'); $cache->clean('com_flexicontent_filters'); // Output new state icon and terminate $tmpparams = new JRegistry(); $tmpparams->set('stateicon_popup', 'basic'); $stateicon = flexicontent_html::stateicon($state, $tmpparams); echo $stateicon; exit; }
/** * Logic to import csv files with content item data * * @access public * @return void * @since 1.5 */ function importcsv() { // Check for request forgeries if (JRequest::getCmd('task') != 'importcsv') { JRequest::checkToken() or jexit('Invalid Token'); echo '<link rel="stylesheet" href="' . JURI::base(true) . '/components/com_flexicontent/assets/css/flexicontentbackend.css?' . FLEXI_VERSION . '" />'; $fc_css = JURI::base(true) . '/components/com_flexicontent/assets/css/j3x.css'; echo '<link rel="stylesheet" href="' . $fc_css . '?' . FLEXI_VERSION . '" />'; } else { // output this before every other output echo 'success||||' . (FLEXI_J30GE ? JSession::getFormToken() : JUtility::getToken()) . '||||'; } // Get item model $itemmodel = $this->getModel('item'); $model = $this->getModel('import'); // Set some variables $link = 'index.php?option=com_flexicontent&view=import'; // $_SERVER['HTTP_REFERER']; $task = JRequest::getCmd('task'); $app = JFactory::getApplication(); $db = JFactory::getDBO(); $user = JFactory::getUser(); $session = JFactory::getSession(); $has_zlib = version_compare(PHP_VERSION, '5.4.0', '>='); $parse_log = "\n\n\n" . '<b>please click</b> <a href="' . $link . '">here</a> to return previous page' . "\n\n\n"; $log_filename = 'importcsv_' . $user->id . '.php'; jimport('joomla.log.log'); JLog::addLogger(array('text_file' => $log_filename)); // ************************* // Execute according to task // ************************* switch ($task) { // *********************************************************************************************** // RESET/CLEAR an already started import task, e.g. import process was interrupted for some reason // *********************************************************************************************** case 'clearcsv': // Clear any import data from session $conf = $has_zlib ? base64_encode(zlib_encode(serialize(null), -15)) : base64_encode(serialize(null)); $session->set('csvimport_config', $conf, 'flexicontent'); $session->set('csvimport_lineno', 0, 'flexicontent'); // Set a message that import task was cleared and redirect $app->enqueueMessage('Import task cleared', 'notice'); $this->setRedirect($link); return; break; // **************************************************** // CONTINUE an already started (multi-step) import task // **************************************************** // **************************************************** // CONTINUE an already started (multi-step) import task // **************************************************** case 'importcsv': $conf = $session->get('csvimport_config', "", 'flexicontent'); $conf = unserialize($conf ? $has_zlib ? zlib_decode(base64_decode($conf)) : base64_decode($conf) : ""); $lineno = $session->get('csvimport_lineno', 999999, 'flexicontent'); if (empty($conf)) { $app->enqueueMessage('Can not continue import, import task not initialized or already finished', 'error'); $this->setRedirect($link); return; } // CONTINUE to do the import // ... break; // ************************************************************************* // INITIALIZE (prepare) import by getting configuration and reading CSV file // ************************************************************************* // ************************************************************************* // INITIALIZE (prepare) import by getting configuration and reading CSV file // ************************************************************************* case 'initcsv': case 'testcsv': $conf = array(); $conf['failure_count'] = $conf['success_count'] = 0; // Retrieve Basic configuration $conf['type_id'] = JRequest::getInt('type_id', 0); $conf['language'] = JRequest::getVar('language', ''); $conf['state'] = JRequest::getInt('state', ''); $conf['access'] = JRequest::getInt('access', ''); // Main and secondary categories $conf['maincat'] = JRequest::getInt('maincat', 0); $conf['maincat_col'] = JRequest::getInt('maincat_col', 0); $conf['seccats'] = JRequest::getVar('seccats', array(), 'post', 'array'); $conf['seccats_col'] = JRequest::getInt('seccats_col', 0); // Tags $conf['tags_col'] = JRequest::getInt('tags_col', 0); // Publication: META data $conf['created_by_col'] = JRequest::getInt('created_by_col', 0); $conf['modified_by_col'] = JRequest::getInt('modified_by_col', 0); // Publication: META data $conf['metadesc_col'] = JRequest::getInt('metadesc_col', 0); $conf['metakey_col'] = JRequest::getInt('metakey_col', 0); // Publication: dates $conf['modified_col'] = JRequest::getInt('modified_col', 0); $conf['created_col'] = JRequest::getInt('created_col', 0); $conf['publish_up_col'] = JRequest::getInt('publish_up_col', 0); $conf['publish_down_col'] = JRequest::getInt('publish_down_col', 0); // Advanced configuration $conf['ignore_unused_cols'] = JRequest::getInt('ignore_unused_cols', 0); $conf['id_col'] = JRequest::getInt('id_col', 0); $conf['items_per_step'] = JRequest::getInt('items_per_step', 5); if ($conf['items_per_step'] > 50) { $conf['items_per_step'] = 50; } if (!$conf['items_per_step']) { $conf['items_per_step'] = 5; } // CSV file format $conf['mval_separator'] = JRequest::getVar('mval_separator'); $conf['mprop_separator'] = JRequest::getVar('mprop_separator'); $conf['field_separator'] = JRequest::getVar('field_separator'); $conf['enclosure_char'] = JRequest::getVar('enclosure_char'); $conf['record_separator'] = JRequest::getVar('record_separator'); $conf['debug_records'] = JRequest::getInt('debug_records', 0); // Debug, print parsed data without importing // ******************************************************************************************** // Obligatory form fields, js validation should have prevented form submission but check anyway // ******************************************************************************************** // Check for the required Content Type Id if (!$conf['type_id']) { $app->enqueueMessage('Please select Content Type for the imported items', 'error'); $app->redirect($link); } // Check for the required main category if (!$conf['maincat'] && !$conf['maincat_col']) { $app->enqueueMessage('Please select main category for the imported items', 'error'); $app->redirect($link); } // ******************************************************************************************************************** // Check for (required) CSV file format variables, js validation should have prevented form submission but check anyway // ******************************************************************************************************************** if ($conf['mval_separator'] == '' || $conf['mprop_separator'] == '') { $app->enqueueMessage('CSV format not valid, please enter multi-value, and multi-property Separators', 'error'); $app->redirect($link); } if ($conf['field_separator'] == '' || $conf['record_separator'] == '') { $app->enqueueMessage('CSV format not valid, please enter Field Separator and Item Separator', 'error'); $app->redirect($link); } // Retrieve the uploaded CSV file $csvfile = @$_FILES["csvfile"]["tmp_name"]; if (!is_file($csvfile)) { $app->enqueueMessage('Upload file error!', 'error'); $app->redirect($link); } // ****************************************************************************************************** // Retrieve CSV file format variables, EXPANDING the Escape Characters like '\n' ... provided by the form // ****************************************************************************************************** $pattern = '/(?<!\\\\)(\\\\(?:n|r|t|v|f|[0-7]{1,3}|x[0-9a-f]{1,2}))/i'; $replace = 'eval(\'return "$1";\')'; $conf['mval_separator'] = preg_replace_callback($pattern, function ($matches) { $r = $matches[1]; eval("\$r = \"{$r}\";"); return $r; }, $conf['mval_separator']); $conf['mprop_separator'] = preg_replace_callback($pattern, function ($matches) { $r = $matches[1]; eval("\$r = \"{$r}\";"); return $r; }, $conf['mprop_separator']); $conf['field_separator'] = preg_replace_callback($pattern, function ($matches) { $r = $matches[1]; eval("\$r = \"{$r}\";"); return $r; }, $conf['field_separator']); $conf['enclosure_char'] = preg_replace_callback($pattern, function ($matches) { $r = $matches[1]; eval("\$r = \"{$r}\";"); return $r; }, $conf['enclosure_char']); $conf['record_separator'] = preg_replace_callback($pattern, function ($matches) { $r = $matches[1]; eval("\$r = \"{$r}\";"); return $r; }, $conf['record_separator']); // **************************************************** // Read & Parse the CSV file according the given format // **************************************************** $contents = FLEXIUtilities::csvstring_to_array(file_get_contents($csvfile), $conf['field_separator'], $conf['enclosure_char'], $conf['record_separator']); // Basic error checking, for empty data if (!$contents || count($contents[0]) <= 0) { $app->enqueueMessage('CSV file format is not correct!', 'error'); $app->redirect($link); } // ******************************************************************************** // Get field names (from the header line (row 0), and remove it form the data array // ******************************************************************************** $conf['columns'] = flexicontent_html::arrayTrim($contents[0]); unset($contents[0]); $q = 'SELECT id, name, field_type, label FROM #__flexicontent_fields AS fi' . ' JOIN #__flexicontent_fields_type_relations AS ftrel ON ftrel.field_id = fi.id AND ftrel.type_id=' . $conf['type_id']; $db->setQuery($q); $conf['thefields'] = $db->loadObjectList('name'); unset($conf['thefields']['tags']); // Prevent Automated Raw insertion of tags, we will use special code // ****************************************************************** // Check for REQUIRED columns and decide CORE property columns to use // ****************************************************************** $core_props = array(); if ($conf['id_col'] && !in_array('id', $conf['columns'])) { $app->enqueueMessage('CSV file lacks column <b>\'id\'</b> (Item ID)', 'error'); $app->redirect($link); } else { if ($conf['id_col']) { $core_props['id'] = 'Item ID'; } } if (!in_array('title', $conf['columns'])) { $app->enqueueMessage('CSV file lacks column <b>\'title\'</b>', 'error'); $app->redirect($link); } $core_props['title'] = 'Title (core)'; $core_props['text'] = 'Description (core)'; $core_props['alias'] = 'Alias (core)'; if (!$conf['language'] && !in_array('language', $conf['columns'])) { $app->enqueueMessage('CSV file lacks column <b>\'language\'</b>', 'error'); $app->redirect($link); } else { if (!$conf['language']) { $core_props['language'] = 'Language'; } } if (!strlen($conf['state']) && !in_array('state', $conf['columns'])) { $app->enqueueMessage('CSV file lacks column <b>\'state\'</b>', 'error'); $app->redirect($link); } else { if (!strlen($conf['state'])) { $core_props['state'] = 'State'; } } if ($conf['access'] === 0 && !in_array('access', $conf['columns'])) { $app->enqueueMessage('CSV file lacks column <b>\'access\'</b>', 'error'); $app->redirect($link); } else { if ($conf['access'] === 0) { $core_props['access'] = 'Access'; } } if ($conf['maincat_col'] && !in_array('catid', $conf['columns'])) { $app->enqueueMessage('CSV file lacks column <b>\'catid\'</b> (Primary category)', 'error'); $app->redirect($link); } else { if ($conf['maincat_col']) { $core_props['catid'] = 'Primary category'; } } if ($conf['seccats_col'] && !in_array('cid', $conf['columns'])) { $app->enqueueMessage('CSV file lacks column <b>\'cid\'</b> (Secondary categories)', 'error'); $app->redirect($link); } else { if ($conf['seccats_col']) { $core_props['cid'] = 'Secondary categories'; } } if ($conf['created_col'] && !in_array('created', $conf['columns'])) { $app->enqueueMessage('CSV file lacks column <b>\'created\'</b> (Creation date)', 'error'); $app->redirect($link); } else { if ($conf['created_col']) { $core_props['created'] = 'Creation Date'; } } if ($conf['created_by_col'] && !in_array('created_by', $conf['columns'])) { $app->enqueueMessage('CSV file lacks column <b>\'created_by\'</b> (Creator - Author)', 'error'); $app->redirect($link); } else { if ($conf['created_by_col']) { $core_props['created_by'] = 'Creator (Author)'; } } if ($conf['modified_col'] && !in_array('modified', $conf['columns'])) { $app->enqueueMessage('CSV file lacks column <b>\'modified\'</b> (Modification date)', 'error'); $app->redirect($link); } else { if ($conf['modified_col']) { $core_props['modified'] = 'Modification Date'; } } if ($conf['modified_by_col'] && !in_array('modified_by', $conf['columns'])) { $app->enqueueMessage('CSV file lacks column <b>\'modified_by\'</b> (Last modifier)', 'error'); $app->redirect($link); } else { if ($conf['modified_by_col']) { $core_props['modified_by'] = 'Last modifier'; } } if ($conf['metadesc_col'] && !in_array('metadesc', $conf['columns'])) { $app->enqueueMessage('CSV file lacks column <b>\'metadesc\'</b> (META Description)', 'error'); $app->redirect($link); } else { if ($conf['metadesc_col']) { $core_props['metadesc'] = 'META Description'; } } if ($conf['metakey_col'] && !in_array('metakey', $conf['columns'])) { $app->enqueueMessage('CSV file lacks column <b>\'metakey\'</b> (META Keywords)', 'error'); $app->redirect($link); } else { if ($conf['metakey_col']) { $core_props['metakey'] = 'META Keywords'; } } if ($conf['publish_up_col'] && !in_array('publish_up', $conf['columns'])) { $app->enqueueMessage('CSV file lacks column <b>\'publish_up\'</b> (Start publication date)', 'error'); $app->redirect($link); } else { if ($conf['publish_up_col']) { $core_props['publish_up'] = 'Start publication date'; } } if ($conf['publish_down_col'] && !in_array('publish_down', $conf['columns'])) { $app->enqueueMessage('CSV file lacks column <b>\'publish_down\'</b> (End publication Date)', 'error'); $app->redirect($link); } else { if ($conf['publish_down_col']) { $core_props['publish_down'] = 'End publication Date'; } } if ($conf['tags_col'] == 1 && !in_array('tags_names', $conf['columns'])) { $app->enqueueMessage('CSV file lacks column <b>\'tags_names\'</b> (Comma separated list of tag names)', 'error'); $app->redirect($link); } else { if ($conf['tags_col'] == 1) { $core_props['tags_names'] = 'Tag names'; $tags_model = $this->getModel('tags'); } } if ($conf['tags_col'] == 2 && !in_array('tags_raw', $conf['columns'])) { $app->enqueueMessage('CSV file lacks column <b>\'tags_raw\'</b> (Comma separated list of tag ids)', 'error'); $app->redirect($link); } else { if ($conf['tags_col'] == 2) { $core_props['tags_raw'] = 'Tags'; $tags_model = $this->getModel('tags'); } } $conf['core_props'] =& $core_props; // ********************************************************* // Verify that all non core property columns are field names // ********************************************************* $unused_columns = array(); foreach ($conf['columns'] as $colname) { if (!isset($conf['core_props'][$colname]) && !isset($conf['thefields'][$colname])) { $unused_columns[] = $colname; if ($conf['ignore_unused_cols']) { JError::raiseNotice(500, "Column '" . $colname . "' : field name NOT FOUND (column will be ignored)"); } } } if (count($unused_columns) && !$conf['ignore_unused_cols']) { $app->enqueueMessage(' File has unused ' . count($unused_columns) . ' columns: <b>' . implode(', ', $unused_columns) . '</b>' . ' <br/>these field names are not assigned to choosen <b>content type</b>' . ' <br/><br/>please enable option: <b>\'Ignore unused columns\'</b>', 'error'); $app->redirect($link); } // ********************************************************** // Verify that custom specified item ids do not already exist // ********************************************************** if ($conf['id_col']) { // Get 'id' column no $id_col_no = 0; foreach ($conf['columns'] as $col_no => $column) { if ($conf['columns'][$col_no] == 'id') { $id_col_no = $col_no; break; } } // Get custom IDs in csv file $custom_id_arr = array(); foreach ($contents as $fields) { $custom_id_arr[] = $fields[$id_col_no]; } $custom_id_list = "'" . implode("','", $custom_id_arr) . "'"; // Cross check them if they already exist in the DB $q = "SELECT id FROM #__content WHERE id IN (" . $custom_id_list . ")"; $db->setQuery($q); $existing_ids = FLEXI_J16GE ? $db->loadColumn() : $db->loadResultArray(); if ($existing_ids && count($existing_ids)) { $app->enqueueMessage('File has ' . count($existing_ids) . ' item IDs that already exist: \'' . implode("\\' , \\'", $existing_ids) . '\', please fix or set to ignore \'id\' column', 'error'); $app->redirect($link); } } // Trim item's data foreach ($contents as $fields) { $fields = flexicontent_html::arrayTrim($fields); } // Set csvfile contens and columns information $conf['contents'] =& $contents; // *************************************************************** // Verify that imported files exist in the media/documents folders // *************************************************************** // Get fields that use files $conf['media_folder'] = JRequest::getVar('media_folder'); $conf['docs_folder'] = JRequest::getVar('docs_folder'); $this->checkfiles($conf, $parse_log, $task); $this->parsevalues($conf, $parse_log, $task); if ($task == 'initcsv') { // Set import configuration and file data into session $session->set('csvimport_config', $has_zlib ? base64_encode(zlib_encode(serialize($conf), -15)) : base64_encode(serialize($conf)), 'flexicontent'); $session->set('csvimport_lineno', 0, 'flexicontent'); // Set a message that import task was prepared and redirect $app->enqueueMessage('Import task prepared. <br/>' . 'File has ' . count($conf['contents_parsed']) . ' records (content items)' . ' and ' . count($conf['columns']) . ' columns (fields)', 'message'); $this->setRedirect($link); return; } else { // task == 'testcsv' $conf['debug_records'] = $conf['debug_records'] ? $conf['debug_records'] : 2; } break; // ************************ // UNKNWOWN task, terminate // ************************ // ************************ // UNKNWOWN task, terminate // ************************ default: // Set an error message about unknown task and redirect $app->enqueueMessage('Unknown task: ' . $task, 'error'); $this->setRedirect($link); return; break; } // ********************************************************************************* // Handle each row (item) using store() method of the item model to create the items // ********************************************************************************* if ($conf['tags_col']) { $tags_model = $this->getModel('tags'); } $colcount = count($conf['columns']); $itemcount = count($conf['contents_parsed']); $items_per_call = JRequest::getInt('items_per_call', 0); JRequest::setVar('import_media_folder', $conf['media_folder']); JRequest::setVar('import_docs_folder', $conf['docs_folder']); $lineno = $task == 'testcsv' ? 1 : $lineno + 1; $linelim = $items_per_call ? $lineno + $items_per_call - 1 : $itemcount; $linelim = $linelim > $itemcount ? $itemcount : $linelim; //echo "lineno: $lineno -- linelim: $linelim<br/>"; for (; $lineno <= $linelim; $lineno++) { $_d =& $conf['contents_parsed'][$lineno]; $data = array(); $data['type_id'] = $conf['type_id']; $data['language'] = $conf['language']; $data['catid'] = $conf['maincat']; // Default value maybe overriden by column $data['cid'] = $conf['seccats']; // Default value maybe overriden by column $data['vstate'] = 2; $data['state'] = $conf['state']; $data['access'] = $conf['access']; // Prepare request variable used by the item's Model if ($task != 'testcsv') { foreach ($_d as $fieldname => $field_values) { if ($fieldname == 'tags_names') { if ($conf['tags_col'] == 1) { // Get tag names from comma separated list, filtering out bad characters $remove = array("\n", "\r\n", "\r"); $tns_list = str_replace($remove, ' ', $field_values); $tns_list = strip_tags($tns_list); $tns_list = preg_replace("/[\"\\\\]/u", "", $tns_list); // "/[\"'\\\]/u" $tns = array_unique(preg_split("/\\s*,\\s*/u", $tns_list)); $tns_quoted = array(); foreach ($tns as $tindex => $tname) { if ($tname) { $tns_quoted[] = $db->Quote($tname); } } if (count($tns_quoted)) { $tns_list_quoted = implode(",", $tns_quoted); $q = "SELECT name FROM #__flexicontent_tags WHERE name IN (" . $tns_list_quoted . ")"; $db->setQuery($q); $tns_e = FLEXI_J16GE ? $db->loadColumn() : $db->loadResultArray(); $tns_m = array_diff($tns, $tns_e); if (count($tns_m)) { // Create a newline separated list of tag names and then import missing tags, // thus making sure they are inserted into the tags DB table if not already present $tns_list_m = implode("\n", $tns_m); $tags_model->importList($tns_list_m); } // Get tag ids $q = "SELECT id FROM #__flexicontent_tags WHERE name IN (" . $tns_list_quoted . ")"; $db->setQuery($q); $data['tag'] = FLEXI_J16GE ? $db->loadColumn() : $db->loadResultArray(); } } } else { if ($fieldname == 'tags_raw') { if ($conf['tags_col'] == 2) { // Get tag ids from comma separated list, filtering out bad characters $_tis_list = preg_replace("/[\"'\\\\]/u", "", $field_values); $_tis = array_unique(array_map('intval', $_tis)); $_tis = array_flip($_tis); // Check to use only existing tag ids $_tis_list = implode(",", array_keys($_tis)); $q = "SELECT id FROM #__flexicontent_tags WHERE id IN (" . $_tis_list . ")"; $db->setQuery($q); $data['tag'] = FLEXI_J16GE ? $db->loadColumn() : $db->loadResultArray(); } } else { if (isset($conf['core_props'][$fieldname])) { $data[$fieldname] = $field_values; } else { if (FLEXI_J16GE) { $data['custom'][$fieldname] = $field_values; } } } } } } // Set/Force id to zero to indicate creation of new item, in case item 'id' column is being used $c_item_id = @$data['id']; $data['id'] = 0; $session->set('csvimport_lineno', $lineno, 'flexicontent'); // If testing format then output some information if ($task == 'testcsv') { if ($lineno == 1) { $parse_log .= ' <span class="fc-mssg fc-info"> Testing file format <br/> COLUMNS: ' . implode(', ', $conf['columns']) . '<br/> </span><hr/> '; } foreach ($_d as $i => $flddata) { if (is_string($_d[$i])) { if (mb_strlen($_d[$i], 'UTF-8') > 80) { $_d[$i] = mb_substr(strip_tags($_d[$i]), 0, 80, 'UTF-8') . ' ... '; } } } if ($lineno <= $conf['debug_records']) { $parse_log .= "<pre><b>Item no {$lineno}:</b>\n" . print_r($_d, true) . "</pre><hr/>"; } else { $parse_log .= "<b>Item no {$lineno}:</b> <br/>" . "<u>TITLE</u>: " . $_d['title'] . "<br/>" . "<u>TEXT</u>: " . $_d['text'] . "<hr/>"; } } else { if (!$itemmodel->store($data)) { $conf['failure_count']++; $msg = 'Failed item no: ' . $lineno . ". titled as: '" . $data['title'] . "' : " . $itemmodel->getError(); JLog::add($msg); echo $msg . "<br/>"; } else { $conf['success_count']++; $msg = 'Imported item no: ' . $lineno . ". titled as: '" . $data['title'] . "'"; JLog::add($msg); echo $msg . "<br/>"; // Try to rename entry if id column is being used if ($conf['id_col'] && $c_item_id) { $item_id = $itemmodel->getId(); $q = "UPDATE #__content SET id='" . $c_item_id . "' WHERE id='" . $item_id . "'"; $db->setQuery($q); $db->execute(); $q = "UPDATE #__flexicontent_items_ext SET item_id='" . $c_item_id . "' WHERE item_id='" . $item_id . "'"; $db->setQuery($q); $db->execute(); $q = "UPDATE #__flexicontent_items_tmp SET id='" . $c_item_id . "' WHERE id='" . $item_id . "'"; $db->setQuery($q); $db->execute(); $q = "UPDATE #__flexicontent_tags_item_relations SET itemid='" . $c_item_id . "' WHERE itemid='" . $item_id . "'"; $db->setQuery($q); $db->execute(); $q = "UPDATE #__flexicontent_cats_item_relations SET itemid='" . $c_item_id . "' WHERE itemid='" . $item_id . "'"; $db->setQuery($q); $db->execute(); $q = "UPDATE #__flexicontent_fields_item_relations SET item_id='" . $c_item_id . "' WHERE item_id='" . $item_id . "'"; $db->setQuery($q); $db->execute(); $q = "UPDATE #__flexicontent_items_versions SET item_id='" . $c_item_id . "' WHERE item_id='" . $item_id . "'"; $db->setQuery($q); $db->execute(); $q = "UPDATE #__flexicontent_versions SET item_id='" . $c_item_id . "' WHERE item_id='" . $item_id . "'"; $db->setQuery($q); $db->execute(); $q = "UPDATE #__flexicontent_favourites SET itemid='" . $c_item_id . "' WHERE itemid='" . $item_id . "'"; $db->setQuery($q); $db->execute(); if (FLEXI_J16GE) { $q = "UPDATE #__assets SET id='" . $c_item_id . "' WHERE id='" . $item_id . "'"; } else { $q = "UPDATE #__flexiaccess_acl SET axo='" . $c_item_id . "'" . " WHERE acosection = " . $db->Quote('com_content') . " AND axosection = " . $db->Quote('item') . " AND axo='" . $item_id . "'"; } $db->setQuery($q); $db->execute(); } } } } //fclose($fp); // Done nothing more to do if ($task == 'testcsv') { echo $parse_log; echo "\n\n\n" . '<b>please click</b> <a href="' . $link . '">here</a> to return previous page' . "\n\n\n"; jexit(); } if ($lineno == $itemcount) { // Clean item's cache $cache = FLEXIUtilities::getCache($group = '', 0); $cache->clean('com_flexicontent_items'); $cache->clean('com_flexicontent_filters'); $cache = FLEXIUtilities::getCache($group = '', 1); $cache->clean('com_flexicontent_items'); $cache->clean('com_flexicontent_filters'); // Set a total results message and redirect $msg = 'Imported items: ' . $conf['success_count'] . ' , failed items: ' . $conf['failure_count'] . ', please review (in the logs folder) the import log file: ' . $log_filename; //$app->enqueueMessage($msg, ($conf['failure_count']==0 && $conf['success_count']>0) ? 'message' : 'warning'); //$this->setRedirect($link); // commented out this via AJAX call now } jexit(); }
/** * Logic to submit item to approval * * @access public * @return void * @since 1.5 */ function approval($cid) { $db = $this->_db; $user = JFactory::getUser(); $approvables = $this->isUserDraft($cid); $requestApproval = FLEXI_J16GE ? $user->authorise('flexicontent.requestapproval', 'com_flexicontent') : $user->gid >= 20; // or at least a J1.5 Editor $submitted = 0; $noprivilege = array(); $checked_out = array(); $publishable = array(); foreach ($approvables as $approvable) { // Check if not owned (while not have global request approval privilege) if (!$requestApproval && $approvable->created_by != (int) $user->get('id')) { $noprivilege[] = $item->title; continue; } // Check if checked out (edited) by different user if ($approvable->checked_out != 0 && $approvable->checked_out != (int) $user->get('id')) { $checked_out[] = $item->title; continue; } // Get item setting it into the model, and get publish privilege $item = $this->getItem($approvable->id, $check_view_access = false, $no_cache = true); $canEditState = $this->canEditState($item, $check_cat_perm = true); if ($canEditState) { $publishable[] = $item->title; continue; } // Set to pending approval $this->setitemstate($approvable->id, -3); $validators = $this->getApprovalRequestReceivers($approvable->id, $approvable->catid); if (!count($validators->notify_emails)) { $validators->notify_emails[] = JFactory::getApplication()->getCfg('mailfrom'); } // Get component parameters and them merge into them the type parameters $params = FLEXI_J16GE ? new JRegistry() : new JParameter(""); $cparams = JComponentHelper::getParams('com_flexicontent'); $params->merge($cparams); $tparams = $this->getTypeparams(); $tparams = FLEXI_J16GE ? new JRegistry($tparams) : new JParameter($tparams); $params->merge($tparams); $query = 'SELECT DISTINCT c.id, c.title FROM #__categories AS c' . ' LEFT JOIN #__flexicontent_cats_item_relations AS rel ON rel.catid = c.id' . ' WHERE rel.itemid = ' . (int) $approvable->id; $db->setQuery($query); $after_cats = $db->loadObjectList('id'); $notify_vars = new stdClass(); $notify_vars->needs_version_reviewal = 0; $notify_vars->needs_publication_approval = 1; $notify_vars->isnew = 1; $notify_vars->notify_emails = $validators->notify_emails; $notify_vars->notify_text = $validators->notify_text; $notify_vars->before_cats = array(); $notify_vars->after_cats = $after_cats; $this->sendNotificationEmails($notify_vars, $params, $manual_approval_request = 1); $submitted++; } // Number of submitted items if ($submitted) { $approve_str = $submitted > 1 ? 'FLEXI_APPROVAL_ITEMS_SUBMITTED' : 'FLEXI_APPROVAL_ITEM_SUBMITTED'; $msg = ($submitted > 1 ? $submitted : '') . JText::_($approve_str); } else { $msg = JText::_('FLEXI_APPROVAL_NO_ITEMS_SUBMITTED'); } // Number of excluded items, and message that items must be owned and in draft state $excluded = count($cid) - $submitted; $msg .= $excluded ? ' ' . $excluded . ' ' . JText::_('FLEXI_APPROVAL_ITEMS_EXCLUDED') : ''; // Message about excluded non-owned items, that are being owned be a different user (this means current user does not have global request approval privilege) if (count($noprivilege)) { $noprivilege_str = '"' . implode('" , "', $noprivilege) . '"'; $msg .= '<div>' . JText::sprintf('FLEXI_APPROVAL_NO_REQUEST_PRIV_EXCLUDED', $noprivilege_str) . '</div>'; } // Message about excluded checked_out items, that are being edited be a different user if (count($checked_out)) { $checked_out_str = '"' . implode('" , "', $checked_out) . '"'; $msg .= '<div>' . JText::sprintf('FLEXI_APPROVAL_CHECKED_OUT_EXCLUDED', $checked_out_str) . '</div>'; } // Message about excluded publishable items, that can be published by the owner if (count($publishable)) { $publishable_str = '"' . implode('" , "', $publishable) . '"'; $msg .= '<div>' . JText::sprintf('FLEXI_APPROVAL_PUBLISHABLE_EXCLUDED', $publishable_str) . '</div>'; } // This may not be needed since the item was already in unpublished stated ?? if (FLEXI_J16GE) { $cache = FLEXIUtilities::getCache($group = '', 0); $cache->clean('com_flexicontent_items'); $cache->clean('com_flexicontent_filters'); $cache = FLEXIUtilities::getCache($group = '', 1); $cache->clean('com_flexicontent_items'); $cache->clean('com_flexicontent_filters'); } else { $itemcache = JFactory::getCache('com_flexicontent_items'); $itemcache->clean(); $filtercache = JFactory::getCache('com_flexicontent_filters'); $filtercache->clean(); } return $msg; }
/** * Logic to save an item * * @access public * @return void * @since 1.0 */ function save() { // Check for request forgeries JRequest::checkToken() or jexit('Invalid Token'); //echo '<html> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <body>'; // Initialize variables $app = JFactory::getApplication(); $db = JFactory::getDBO(); $user = JFactory::getUser(); $config = JFactory::getConfig(); $session = JFactory::getSession(); $task = JRequest::getVar('task'); $ctrl_task = 'task=items.'; // ********************* // Get data from request // ********************* // Retrieve form data these are subject to basic filtering $data = JRequest::getVar('jform', array(), 'post', 'array'); // Core Fields and and item Parameters $custom = JRequest::getVar('custom', array(), 'post', 'array'); // Custom Fields $jfdata = JRequest::getVar('jfdata', array(), 'post', 'array'); // Joomfish Data // Set into model: id (needed for loading correct item), and type id (e.g. needed for getting correct type parameters for new items) $data_id = (int) $data['id']; $isnew = $data_id == 0; // If new make sure that type id is set too, before creating the model if ($isnew) { $typeid = JRequest::setvar('typeid', (int) @$data['type_id']); } // Get the model $model = $this->getModel('item'); $model->setId($data_id); // Make sure id is correct // Get some flags this will also trigger item loading if not already loaded $isOwner = $model->get('created_by') == $user->get('id'); // Get merged parameters: component, type, menu $params = new JRegistry(); $model_params = $model->getComponentTypeParams(); $params->merge($model_params); // Merge the active menu parameters $menu = $app->getMenu()->getActive(); if ($menu) { $params->merge($menu->params); } // Get some needed parameters $submit_redirect_url_fe = $params->get('submit_redirect_url_fe', ''); $allowunauthorize = $params->get('allowunauthorize', 0); $dolog = $params->get('print_logging_info'); // Unique id for new items, needed by some fields for temporary data $unique_tmp_itemid = JRequest::getVar('unique_tmp_itemid'); // Auto title for some content types if ($params->get('auto_title', 0)) { $data['title'] = (int) $data['id']; } // item id or ZERO for new items if (!@$data['rules']) { $data['rules'] = array(); } // We use some strings from administrator part, load english language file // for 'com_flexicontent' component then override with current language file JFactory::getLanguage()->load('com_flexicontent', JPATH_ADMINISTRATOR, 'en-GB', true); JFactory::getLanguage()->load('com_flexicontent', JPATH_ADMINISTRATOR, null, true); // ************************************* // ENFORCE can change category ACL perms // ************************************* $perms = FlexicontentHelperPerm::getPerm(); // Per content type change category permissions $current_type_id = $isnew || !$model->get('type_id') ? (int) @$data['type_id'] : $model->get('type_id'); // GET current (existing/old) item TYPE ID $CanChangeFeatCat = $user->authorise('flexicontent.change.cat.feat', 'com_flexicontent.type.' . $current_type_id); $CanChangeSecCat = $user->authorise('flexicontent.change.cat.sec', 'com_flexicontent.type.' . $current_type_id); $CanChangeCat = $user->authorise('flexicontent.change.cat', 'com_flexicontent.type.' . $current_type_id); $AutoApproveChanges = $perms->AutoApproveChanges; $enable_featured_cid_selector = $perms->MultiCat && $CanChangeFeatCat; $enable_cid_selector = $perms->MultiCat && $CanChangeSecCat; $enable_catid_selector = $isnew && !$params->get('catid_default') || !$isnew && !$model->get('catid') || $CanChangeCat; // Enforce maintaining featured categories $featured_cats_parent = $params->get('featured_cats_parent', 0); $featured_cats = array(); if ($featured_cats_parent && !$enable_featured_cid_selector) { $featured_tree = flexicontent_cats::getCategoriesTree($published_only = 1, $parent_id = $featured_cats_parent, $depth_limit = 0); $disabled_cats = $params->get('featured_cats_parent_disable', 1) ? array($featured_cats_parent) : array(); $featured_cid = array(); if (!$isnew) { foreach ($model->get('categories') as $item_cat) { if (isset($featured_tree[$item_cat]) && !isset($disabled_cats[$item_cat])) { $featured_cid[] = $item_cat; } } } $data['featured_cid'] = $featured_cid; } // Enforce maintaining secondary categories if (!$enable_cid_selector && (empty($data['submit_conf']) || empty($data['cid']))) { // respect submit menu cat override if ($isnew) { $data['cid'] = $params->get('cid_default'); } else { if (isset($featured_cid)) { $featured_cid_arr = array_flip($featured_cid); $sec_cid = array(); foreach ($model->get('cats') as $item_cat) { if (!isset($featured_cid_arr[$item_cat])) { $sec_cid[] = $item_cat; } } $data['cid'] = $sec_cid; } else { $data['cid'] = $model->get('cats'); } } } if (!$enable_catid_selector && (empty($data['submit_conf']) || empty($data['catid']))) { // respect submit menu cat override if ($isnew && $params->get('catid_default')) { $data['catid'] = $params->get('catid_default'); } else { if ($model->get('catid')) { $data['catid'] = $model->get('catid'); } } } // ************************** // Basic Form data validation // ************************** // Get the JForm object, but do not pass any data we only want the form object, // in order to validate the data and not create a filled-in form $form = $model->getForm(); // *** MANUALLY CHECK CAPTCHA *** $use_captcha = $params->get('use_captcha', 1); // 1 for guests, 2 for any user $captcha_formop = $params->get('captcha_formop', 0); // 0 for submit, 1 for submit/edit (aka always) $is_submitop = (int) $data['id'] == 0; $display_captcha = $use_captcha >= 2 || $use_captcha == 1 && $user->guest; $display_captcha = $display_captcha && ($is_submitop || $captcha_formop); // for submit operation we do not need to check 'captcha_formop' ... if ($display_captcha) { $c_plugin = $params->get('captcha', $app->getCfg('captcha')); // TODO add param to override default if ($c_plugin) { $c_name = 'captcha_response_field'; $c_value = JRequest::getString($c_name); $c_id = $c_plugin == 'recaptcha' ? 'dynamic_recaptcha_1' : 'fc_dynamic_captcha'; $c_namespace = 'fc_item_form'; $captcha_obj = JCaptcha::getInstance($c_plugin, array('namespace' => $c_namespace)); if (!$captcha_obj->checkAnswer($c_value)) { // Get the captch validation message and push it out to the user //$error = $captcha_obj->getError(); //$app->enqueueMessage($error instanceof Exception ? $error->getMessage() : $error, 'error'); $app->enqueueMessage(JText::_('FLEXI_CAPTCHA_FAILED') . ' ' . JText::_('FLEXI_MUST_REFILL_SOME_FIELDS'), 'error'); // Set POST form date into the session, so that they get reloaded $app->setUserState($form->option . '.edit.' . $form->context . '.data', $data); // Save the jform data in the session. $app->setUserState($form->option . '.edit.' . $form->context . '.custom', $custom); // Save the custom fields data in the session. $app->setUserState($form->option . '.edit.' . $form->context . '.jfdata', $jfdata); // Save the falang translations into the session $app->setUserState($form->option . '.edit.' . $form->context . '.unique_tmp_itemid', $unique_tmp_itemid); // Save temporary unique item id into the session // Redirect back to the item form $this->setRedirect($_SERVER['HTTP_REFERER']); if (JRequest::getVar('fc_doajax_submit')) { echo flexicontent_html::get_system_messages_html(); exit; // Ajax submit, do not rerender the view } return false; } } } // Validate Form data for core fields and for parameters $post = $model->validate($form, $data); // Check for validation error if (!$post) { // Get the validation messages and push up to three validation messages out to the user $errors = $form->getErrors(); for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) { $app->enqueueMessage($errors[$i] instanceof Exception ? $errors[$i]->getMessage() : $errors[$i], 'error'); } // Set POST form date into the session, so that they get reloaded $app->setUserState($form->option . '.edit.' . $form->context . '.data', $data); // Save the jform data in the session $app->setUserState($form->option . '.edit.' . $form->context . '.custom', $custom); // Save the custom fields data in the session $app->setUserState($form->option . '.edit.' . $form->context . '.jfdata', $jfdata); // Save the falang translations into the session $app->setUserState($form->option . '.edit.' . $form->context . '.unique_tmp_itemid', $unique_tmp_itemid); // Save temporary unique item id into the session // Redirect back to the item form $this->setRedirect($_SERVER['HTTP_REFERER']); if (JRequest::getVar('fc_doajax_submit')) { echo flexicontent_html::get_system_messages_html(); exit; // Ajax submit, do not rerender the view } return false; //die('error'); } // Some values need to be assigned after validation $post['attribs'] = @$data['attribs']; // Workaround for item's template parameters being clear by validation since they are not present in item.xml $post['custom'] =& $custom; // Assign array of custom field values, they are in the 'custom' form array instead of jform $post['jfdata'] =& $jfdata; // Assign array of Joomfish field values, they are in the 'jfdata' form array instead of jform // Assign template parameters of the select ilayout as an sub-array (the DB model will handle the merging of parameters) $ilayout = @$data['attribs']['ilayout']; // normal not be set if frontend template editing is not shown if ($ilayout && !empty($data['layouts'][$ilayout])) { $post['attribs']['layouts'] = $data['layouts']; } //echo "<pre>"; print_r($post['attribs']); exit; // USEFULL FOR DEBUGING for J2.5 (do not remove commented code) //$diff_arr = array_diff_assoc ( $data, $post); //echo "<pre>"; print_r($diff_arr); jexit(); // ******************************************************************************** // PERFORM ACCESS CHECKS, NOTE: we need to check access again, despite having // checked them on edit form load, because user may have tampered with the form ... // ******************************************************************************** $itemAccess = $model->getItemAccess(); $canAdd = $itemAccess->get('access-create'); // includes check of creating in at least one category $canEdit = $itemAccess->get('access-edit'); // includes privileges edit and edit-own $type_id = (int) @$post['type_id']; // Typecast to int, (already done for J2.5 via validating) if (!$isnew && $model->get('type_id') == $type_id) { // Existing item with Type not being ALTERED, content type can be maintained regardless of privilege $canCreateType = true; } else { // New item or existing item with Type is being ALTERED, check privilege to create items of this type $canCreateType = $model->canCreateType(array($type_id), true, $types); } // ***************************************************************** // Calculate user's CREATE / EDIT privileges on current content item // ***************************************************************** $hasCoupon = false; // Normally used in frontend only if (!$isnew) { // If no edit privilege, check if item is editable till logoff if (!$canEdit) { if ($session->has('rendered_uneditable', 'flexicontent')) { $rendered_uneditable = $session->get('rendered_uneditable', array(), 'flexicontent'); $canEdit = isset($rendered_uneditable[$model->get('id')]) && $rendered_uneditable[$model->get('id')]; $hasCoupon = isset($rendered_uneditable[$model->get('id')]) && $rendered_uneditable[$model->get('id')] == 2; // editable via coupon } } } else { // Allow creating via submit menu OVERRIDE if ($allowunauthorize) { $canAdd = true; $canCreateType = true; } } // New item: check if user can create in at least one category if ($isnew && !$canAdd) { JError::raiseWarning(403, JText::_('FLEXI_NO_ACCESS_CREATE')); $this->setRedirect($_SERVER['HTTP_REFERER']); if (JRequest::getVar('fc_doajax_submit')) { echo flexicontent_html::get_system_messages_html(); exit; // Ajax submit, do not rerender the view } return; } // Existing item: Check if user can edit current item if (!$isnew && !$canEdit) { JError::raiseWarning(403, JText::_('FLEXI_NO_ACCESS_EDIT')); $this->setRedirect($_SERVER['HTTP_REFERER']); if (JRequest::getVar('fc_doajax_submit')) { echo flexicontent_html::get_system_messages_html(); exit; // Ajax submit, do not rerender the view } return; } if (!$canCreateType) { $msg = isset($types[$type_id]) ? JText::sprintf('FLEXI_NO_ACCESS_CREATE_CONTENT_OF_TYPE', JText::_($types[$type_id]->name)) : ' Content Type ' . $type_id . ' was not found OR is not published'; JError::raiseWarning(403, $msg); $this->setRedirect($_SERVER['HTTP_REFERER']); if (JRequest::getVar('fc_doajax_submit')) { echo flexicontent_html::get_system_messages_html(); exit; // Ajax submit, do not rerender the view } return; } // Get "BEFORE SAVE" categories for information mail $before_cats = array(); if (!$isnew) { $query = 'SELECT DISTINCT c.id, c.title FROM #__categories AS c' . ' JOIN #__flexicontent_cats_item_relations AS rel ON rel.catid = c.id' . ' WHERE rel.itemid = ' . (int) $model->get('id'); $db->setQuery($query); $before_cats = $db->loadObjectList('id'); $before_maincat = $model->get('catid'); $original_item = $model->getItem($post['id'], $check_view_access = false, $no_cache = true, $force_version = 0); } // **************************************** // Try to store the form data into the item // **************************************** if (!$model->store($post)) { // Set error message about saving failed, and also the reason (=model's error message) $msg = JText::_('FLEXI_ERROR_STORING_ITEM'); JError::raiseWarning(500, $msg . ": " . $model->getError()); // Set POST form date into the session, so that they get reloaded $app->setUserState($form->option . '.edit.' . $form->context . '.data', $data); // Save the jform data in the session $app->setUserState($form->option . '.edit.' . $form->context . '.custom', $custom); // Save the custom fields data in the session $app->setUserState($form->option . '.edit.' . $form->context . '.jfdata', $jfdata); // Save the falang translations into the session $app->setUserState($form->option . '.edit.' . $form->context . '.unique_tmp_itemid', $unique_tmp_itemid); // Save temporary unique item id into the session // Saving has failed check-in and redirect back to the item form, // redirect back to the item form reloading the posted data $model->checkin(); $this->setRedirect($_SERVER['HTTP_REFERER']); if (JRequest::getVar('fc_doajax_submit')) { echo flexicontent_html::get_system_messages_html(); exit; // Ajax submit, do not rerender the view } return; //die('save error'); } // ************************************************** // Check in model and get item id in case of new item // ************************************************** $model->checkin(); $post['id'] = $isnew ? (int) $model->get('id') : $post['id']; // Get items marked as newly submitted $newly_submitted = $session->get('newly_submitted', array(), 'flexicontent'); if ($isnew) { // Mark item as newly submitted, to allow to a proper "THANKS" message after final save & close operation (since user may have clicked add instead of add & close) $newly_submitted[$model->get('id')] = 1; $session->set('newly_submitted', $newly_submitted, 'flexicontent'); } $newly_submitted_item = @$newly_submitted[$model->get('id')]; // *********************************************************************************************************** // Get newly saved -latest- version (store task gets latest) of the item, and also calculate publish privelege // *********************************************************************************************************** $item = $model->getItem($post['id'], $check_view_access = false, $no_cache = true, $force_version = -1); $canPublish = $model->canEditState($item, $check_cat_perm = true) || $hasCoupon; // ******************************************************************************************** // Use session to detect multiple item saves to avoid sending notification EMAIL multiple times // ******************************************************************************************** $is_first_save = true; if ($session->has('saved_fcitems', 'flexicontent')) { $saved_fcitems = $session->get('saved_fcitems', array(), 'flexicontent'); $is_first_save = $isnew ? true : !isset($saved_fcitems[$model->get('id')]); } // Add item to saved items of the corresponding session array $saved_fcitems[$model->get('id')] = $timestamp = time(); // Current time as seconds since Unix epoc; $session->set('saved_fcitems', $saved_fcitems, 'flexicontent'); // ******************************************** // Get categories added / removed from the item // ******************************************** $query = 'SELECT DISTINCT c.id, c.title FROM #__categories AS c' . ' JOIN #__flexicontent_cats_item_relations AS rel ON rel.catid = c.id' . ' WHERE rel.itemid = ' . (int) $model->get('id'); $db->setQuery($query); $after_cats = $db->loadObjectList('id'); if (!$isnew) { $cats_added_ids = array_diff(array_keys($after_cats), array_keys($before_cats)); foreach ($cats_added_ids as $cats_added_id) { $cats_added_titles[] = $after_cats[$cats_added_id]->title; } $cats_removed_ids = array_diff(array_keys($before_cats), array_keys($after_cats)); foreach ($cats_removed_ids as $cats_removed_id) { $cats_removed_titles[] = $before_cats[$cats_removed_id]->title; } $cats_altered = count($cats_added_ids) + count($cats_removed_ids); $after_maincat = $model->get('catid'); } // ******************************************************************************************************************* // We need to get emails to notify, from Global/item's Content Type parameters -AND- from item's categories parameters // ******************************************************************************************************************* $notify_emails = array(); if ($is_first_save || $cats_altered || $params->get('nf_enable_debug', 0)) { // Get needed flags regarding the saved items $approve_version = 2; $pending_approval_state = -3; $draft_state = -4; $current_version = FLEXIUtilities::getCurrentVersions($item->id, true); // Get current item version $last_version = FLEXIUtilities::getLastVersions($item->id, true); // Get last version (=latest one saved, highest version id), // $post variables vstate & state may have been (a) tampered in the form, and/or (b) altered by save procedure so better not use them $needs_version_reviewal = !$isnew && $last_version > $current_version && !$canPublish && !$AutoApproveChanges; $needs_publication_approval = $isnew && $item->state == $pending_approval_state && !$canPublish; $draft_from_non_publisher = $item->state == $draft_state && !$canPublish; if ($draft_from_non_publisher) { // Suppress notifications for draft-state items (new or existing ones), for these each author will publication approval manually via a button $nConf = false; } else { // Get notifications configuration and select appropriate emails for current saving case $nConf = $model->getNotificationsConf($params); //echo "<pre>"; print_r($nConf); "</pre>"; } if ($nConf) { $states_notify_new = $params->get('states_notify_new', array(1, 0, FLEXI_J16GE ? 2 : -1, -3, -4, -5)); if (empty($states_notify_new)) { $states_notify_new = array(); } else { if (!is_array($states_notify_new)) { $states_notify_new = !FLEXI_J16GE ? array($states_notify_new) : explode("|", $states_notify_new); } } $states_notify_existing = $params->get('states_notify_existing', array(1, 0, FLEXI_J16GE ? 2 : -1, -3, -4, -5)); if (empty($states_notify_existing)) { $states_notify_existing = array(); } else { if (!is_array($states_notify_existing)) { $states_notify_existing = !FLEXI_J16GE ? array($states_notify_existing) : explode("|", $states_notify_existing); } } $n_state_ok = in_array($item->state, $states_notify_new); $e_state_ok = in_array($item->state, $states_notify_existing); if ($needs_publication_approval) { $notify_emails = $nConf->emails->notify_new_pending; } else { if ($isnew && $n_state_ok) { $notify_emails = $nConf->emails->notify_new; } else { if ($isnew) { $notify_emails = array(); } else { if ($needs_version_reviewal) { $notify_emails = $nConf->emails->notify_existing_reviewal; } else { if (!$isnew && $e_state_ok) { $notify_emails = $nConf->emails->notify_existing; } else { if (!$isnew) { $notify_emails = array(); } } } } } } if ($needs_publication_approval) { $notify_text = $params->get('text_notify_new_pending'); } else { if ($isnew) { $notify_text = $params->get('text_notify_new'); } else { if ($needs_version_reviewal) { $notify_text = $params->get('text_notify_existing_reviewal'); } else { if (!$isnew) { $notify_text = $params->get('text_notify_existing'); } } } } //print_r($notify_emails); jexit(); } } // ********************************************************************************************************************* // If there are emails to notify for current saving case, then send the notifications emails, but // ********************************************************************************************************************* if (!empty($notify_emails) && count($notify_emails)) { $notify_vars = new stdClass(); $notify_vars->needs_version_reviewal = $needs_version_reviewal; $notify_vars->needs_publication_approval = $needs_publication_approval; $notify_vars->isnew = $isnew; $notify_vars->notify_emails = $notify_emails; $notify_vars->notify_text = $notify_text; $notify_vars->before_cats = $before_cats; $notify_vars->after_cats = $after_cats; $notify_vars->original_item = @$original_item; $model->sendNotificationEmails($notify_vars, $params, $manual_approval_request = 0); } // *************************************************** // CLEAN THE CACHE so that our changes appear realtime // *************************************************** $cache = FLEXIUtilities::getCache($group = '', 0); $cache->clean('com_flexicontent_items'); $cache->clean('com_flexicontent_filters'); $cache = FLEXIUtilities::getCache($group = '', 1); $cache->clean('com_flexicontent_items'); $cache->clean('com_flexicontent_filters'); // **************************************************************************************************************************** // Recalculate EDIT PRIVILEGE of new item. Reason for needing to do this is because we can have create permission in a category // and thus being able to set this category as item's main category, but then have no edit/editown permission for this category // **************************************************************************************************************************** $asset = 'com_content.article.' . $model->get('id'); $canEdit = $user->authorise('core.edit', $asset) || $user->authorise('core.edit.own', $asset) && $isOwner; // ALTERNATIVE 1 //$canEdit = $model->getItemAccess()->get('access-edit'); // includes privileges edit and edit-own // ALTERNATIVE 2 //$rights = FlexicontentHelperPerm::checkAllItemAccess($user->get('id'), 'item', $model->get('id')); //$canEdit = in_array('edit', $rights) || (in_array('edit.own', $rights) && $isOwner) ; // ******************************************************************************************************* // Check if user can not edit item further (due to changed main category, without edit/editown permission) // ******************************************************************************************************* if (!$canEdit) { if ($task == 'apply' || $task == 'apply_type') { // APPLY TASK: Temporarily set item to be editable till closing it and not through all session // (we will/should clear this flag when item is closed, since we have another flag to indicate new items $rendered_uneditable = $session->get('rendered_uneditable', array(), 'flexicontent'); $rendered_uneditable[$model->get('id')] = -1; $session->set('rendered_uneditable', $rendered_uneditable, 'flexicontent'); $canEdit = 1; } else { if ($newly_submitted_item) { // NEW ITEM: Do not use editable till logoff behaviour // ALSO: Clear editable FLAG set in the case that 'apply' button was used during new item creation if (!$params->get('items_session_editable', 0)) { $rendered_uneditable = $session->get('rendered_uneditable', array(), 'flexicontent'); if (isset($rendered_uneditable[$model->get('id')])) { unset($rendered_uneditable[$model->get('id')]); $session->set('rendered_uneditable', $rendered_uneditable, 'flexicontent'); } } } else { // EXISTING ITEM: (if enabled) Use the editable till logoff behaviour if ($params->get('items_session_editable', 0)) { // Set notice for existing item being editable till logoff JError::raiseNotice(403, JText::_('FLEXI_CANNOT_EDIT_AFTER_LOGOFF')); // Allow item to be editable till logoff $rendered_uneditable = $session->get('rendered_uneditable', array(), 'flexicontent'); $rendered_uneditable[$model->get('id')] = 1; $session->set('rendered_uneditable', $rendered_uneditable, 'flexicontent'); $canEdit = 1; } } } // Set notice about saving an item that cannot be changed further if (!$canEdit) { $app->enqueueMessage(JText::_('FLEXI_CANNOT_MAKE_FURTHER_CHANGES_TO_CONTENT'), 'message'); } } // **************************************************************** // Check for new Content Item is being closed, and clear some flags // **************************************************************** if ($task != 'apply' && $task != 'apply_type' && $newly_submitted_item) { // Clear item from being marked as newly submitted unset($newly_submitted[$model->get('id')]); $session->set('newly_submitted', $newly_submitted, 'flexicontent'); // The 'apply' task may set 'editable till logoff' FLAG ... // CLEAR IT, since NEW content this is meant to be used temporarily if (!$params->get('items_session_editable', 0)) { $rendered_uneditable = $session->get('rendered_uneditable', array(), 'flexicontent'); if (isset($rendered_uneditable[$model->get('id')])) { unset($rendered_uneditable[$model->get('id')]); $session->set('rendered_uneditable', $rendered_uneditable, 'flexicontent'); } } } // **************************************** // Saving is done, decide where to redirect // **************************************** // REDIRECT CASE FOR APPLYING: Save and reload the item edit form if ($task == 'apply' || $task == 'apply_type') { $msg = JText::_('FLEXI_ITEM_SAVED'); // Create the URL global $globalcats; $Itemid = JRequest::getInt('Itemid', 0); // maintain current menu item if this was given $item_url = JRoute::_(FlexicontentHelperRoute::getItemRoute($item->id . ':' . $item->alias, $globalcats[$item->catid]->slug, $Itemid)); $link = $item_url . (strstr($item_url, '?') ? '&' : '?') . 'task=edit'; // Important pass referer back to avoid making the form itself the referer // but also check that referer URL is 'safe' (allowed) , e.g. not an offsite URL, otherwise set referer to HOME page $referer = JRequest::getString('referer', JURI::base(), 'post'); if (!flexicontent_html::is_safe_url($referer)) { $referer = JURI::base(); } $return = '&return=' . base64_encode($referer); $link .= $return; } else { // REDIRECT CASE: Return to a custom page after creating a new item (e.g. a thanks page) if ($newly_submitted_item && $submit_redirect_url_fe) { $link = $submit_redirect_url_fe; $msg = JText::_('FLEXI_ITEM_SAVED'); } else { if ($task == 'save_a_preview') { $msg = JText::_('FLEXI_ITEM_SAVED'); $link = JRoute::_(FlexicontentHelperRoute::getItemRoute($model->_item->id . ':' . $model->_item->alias, $model->_item->catid, 0, $model->_item) . '&preview=1', false); } else { $msg = $newly_submitted_item ? JText::_('FLEXI_THANKS_SUBMISSION') : JText::_('FLEXI_ITEM_SAVED'); // Check that referer URL is 'safe' (allowed) , e.g. not an offsite URL, otherwise for returning to HOME page $link = JRequest::getString('referer', JURI::base(), 'post'); if (!flexicontent_html::is_safe_url($link)) { if ($dolog) { JFactory::getApplication()->enqueueMessage('refused redirection to possible unsafe URL: ' . $link, 'notice'); } $link = JURI::base(); } } } } $this->setRedirect($link, $msg); }
/** * Method to reset votes * * @since 1.0 */ function resetvotes() { $id = JRequest::getInt('id', 0); $model = $this->getModel('item'); $model->resetVotes($id); if (FLEXI_J16GE) { $cache = FLEXIUtilities::getCache(); $cache->clean('com_flexicontent_items'); } else { $itemcache = JFactory::getCache('com_flexicontent_items'); $itemcache->clean(); } echo JText::_('FLEXI_NOT_RATED_YET'); }
/** * Logic to save an item * * @access public * @return void * @since 1.0 */ function save() { // Check for request forgeries JRequest::checkToken() or jexit( 'Invalid Token' ); // Initialize variables $app = JFactory::getApplication(); $db = JFactory::getDBO(); $user = JFactory::getUser(); $menu = $app->getMenu()->getActive(); $config = JFactory::getConfig(); $session = JFactory::getSession(); $task = JRequest::getVar('task'); $model = $this->getModel(FLEXI_ITEMVIEW); $isnew = !$model->getId(); $ctrl_task = FLEXI_J16GE ? 'task=items.' : 'controller=items&task='; $fc_params = JComponentHelper::getParams( 'com_flexicontent' ); $dolog = $fc_params->get('print_logging_info'); // Get the COMPONENT only parameters $comp_params = JComponentHelper::getComponent('com_flexicontent')->params; $params = FLEXI_J16GE ? clone ($comp_params) : new JParameter( $comp_params ); // clone( JComponentHelper::getParams('com_flexicontent') ); // Merge the type parameters $tparams = $model->getTypeparams(); $tparams = FLEXI_J16GE ? new JRegistry($tparams) : new JParameter($tparams); $params->merge($tparams); // Merge the menu parameters if ($menu) { $menu_params = FLEXI_J16GE ? $menu->params : new JParameter($menu->params); $params->merge($menu_params); } // Get needed parameters $submit_redirect_url_fe = $params->get('submit_redirect_url_fe', ''); $allowunauthorize = $params->get('allowunauthorize', 0); // ********************* // Get data from request // ********************* if (FLEXI_J16GE) { // Retrieve form data these are subject to basic filtering $data = JRequest::getVar('jform', array(), 'post', 'array'); // Core Fields and and item Parameters $custom = JRequest::getVar('custom', array(), 'post', 'array'); // Custom Fields $jfdata = JRequest::getVar('jfdata', array(), 'post', 'array'); // Joomfish Data if ( ! @ $data['rules'] ) $data['rules'] = array(); } else { // Retrieve form data these are subject to basic filtering $data = JRequest::get( 'post' ); // Core & Custom Fields and item Parameters } // Set data id into model in case not already set ? $model->setId((int) $data['id']); // ************************************* // ENFORCE can change category ACL perms // ************************************* $perms = FlexicontentHelperPerm::getPerm(); // Per content type change category permissions if (FLEXI_J16GE) { $current_type_id = ($isnew || !$model->get('type_id')) ? $data['type_id'] : $model->get('type_id'); // GET current (existing/old) item TYPE ID $CanChangeFeatCat = $user->authorise('flexicontent.change.cat.feat', 'com_flexicontent.type.' . $current_type_id); $CanChangeSecCat = $user->authorise('flexicontent.change.cat.sec', 'com_flexicontent.type.' . $current_type_id); $CanChangeCat = $user->authorise('flexicontent.change.cat', 'com_flexicontent.type.' . $current_type_id); } else { $CanChangeFeatCat = 1; $CanChangeSecCat = 1; $CanChangeCat = 1; } $featured_cats_parent = $params->get('featured_cats_parent', 0); $featured_cats = array(); $enable_featured_cid_selector = $perms->MultiCat && $CanChangeFeatCat; $enable_cid_selector = $perms->MultiCat && $CanChangeSecCat; $enable_catid_selector = ($isnew && !$tparams->get('catid_default')) || (!$isnew && !$model->get('catid')) || $CanChangeCat; // Enforce maintaining featured categories $featured_cats_parent = $params->get('featured_cats_parent', 0); $featured_cats = array(); if ( $featured_cats_parent && !$enable_featured_cid_selector ) { $featured_tree = flexicontent_cats::getCategoriesTree($published_only=1, $parent_id=$featured_cats_parent, $depth_limit=0); $featured_cid = array(); if (!$isnew) { foreach($model->get('categories') as $item_cat) if (isset($featured_tree[$item_cat])) $featured_cid[] = $item_cat; } $data['featured_cid'] = $featured_cid; } // Enforce maintaining secondary categories if (!$enable_cid_selector) { if ($isnew) { $data['cid'] = $tparams->get('cid_default'); } else if ( isset($featured_cid) ) { $featured_cid_arr = array_flip($featured_cid); $sec_cid = array(); foreach($model->get('cats') as $item_cat) if (!isset($featured_cid_arr[$item_cat])) $sec_cid[] = $item_cat; $data['cid'] = $sec_cid; } else { $data['cid'] = $model->get('cats'); } } if (!$enable_catid_selector) { if ($isnew && $tparams->get('catid_default')) $data['catid'] = $tparams->get('catid_default'); else if ($model->get('catid')) $data['catid'] = $model->get('catid'); } // ************************** // Basic Form data validation // ************************** if (FLEXI_J16GE) { // *** MANUALLY CHECK CAPTCHA *** $use_captcha = $params->get('use_captcha', 1); // 1 for guests, 2 for any user $captcha_formop = $params->get('captcha_formop', 0); // 0 for submit, 1 for submit/edit (aka always) $is_submitop = ((int) $data['id']) == 0; $display_captcha = $use_captcha >= 2 || ( $use_captcha == 1 && $user->guest ); $display_captcha = $display_captcha && ( $is_submitop || $captcha_formop); // for submit operation we do not need to check 'captcha_formop' ... if ($display_captcha) { // Try to force the use of recaptcha plugin JFactory::getConfig()->set('captcha', 'recaptcha'); if ( $app->getCfg('captcha') == 'recaptcha' && JPluginHelper::isEnabled('captcha', 'recaptcha') ) { JPluginHelper::importPlugin('captcha'); $dispatcher = JDispatcher::getInstance(); $result = $dispatcher->trigger('onCheckAnswer', JRequest::getString('recaptcha_response_field')); if (!$result[0]) { $errmsg = JText::_('FLEXI_CAPTCHA_FAILED'); $errmsg .= ' '.JText::_('FLEXI_MUST_REFILL_SOME_FIELDS'); echo "<script>alert('".$errmsg."');"; echo "window.history.back();"; echo "</script>"; jexit(); } } } // Validate Form data for core fields and for parameters $form = $model->getForm(); // Do not pass any data we only want the form object in order to validate the data and not create a filled-in form $post = $model->validate($form, $data); // Check for validation error if (!$post) { // Get the validation messages. $errors = $form->getErrors(); // Push up to three validation messages out to the user. for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) { if ($errors[$i] instanceof Exception) $app->enqueueMessage($errors[$i]->getMessage(), 'notice'); else $app->enqueueMessage($errors[$i], 'notice'); } // Save the jform data in the session. $app->setUserState($form->option.'.edit.'.$form->context.'.data', $data); // Save the custom fields data in the session. $app->setUserState($form->option.'.edit.'.$form->context.'.custom', $custom); // Redirect back to the registration form. $this->setRedirect( $_SERVER['HTTP_REFERER'] ); return false; //die('error'); } /*if (!$post) { //JError::raiseWarning( 500, "Error while validating data: " . $model->getError() ); echo "Error while validating data: " . $model->getError(); echo '<span class="fc_return_msg">'.JText::sprintf('FLEXI_CLICK_HERE_TO_RETURN', '"JavaScript:window.history.back();"').'</span>'; jexit(); }*/ // Some values need to be assigned after validation $post['attribs'] = @$data['attribs']; // Workaround for item's template parameters being clear by validation since they are not present in item.xml $post['custom'] = & $custom; // Assign array of custom field values, they are in the 'custom' form array instead of jform $post['jfdata'] = & $jfdata; // Assign array of Joomfish field values, they are in the 'jfdata' form array instead of jform // Assign template parameters of the select ilayout as an sub-array (the DB model will handle the merging of parameters) $ilayout = @ $data['attribs']['ilayout']; // normal not be set if frontend template editing is not shown if( $ilayout && !empty($data['layouts'][$ilayout]) ) $post['attribs']['layouts'] = $data['layouts']; //echo "<pre>"; print_r($post['attribs']); exit; } else { $post = $data; // Some values need to be assigned after validation $post['text'] = JRequest::getVar( 'text', '', 'post', 'string', JREQUEST_ALLOWRAW ); // Workaround for allowing raw text field // Assign template parameters of the select ilayout as an sub-array (the DB model will handle the merging of parameters) $ilayout = @ $post['params']['ilayout']; // normal not be set if frontend template editing is not shown if( $ilayout && !empty($post['layouts'][$ilayout]) ) $post['params']['layouts'] = $post['layouts']; //echo "<pre>"; print_r($post['params']); exit; } // USEFULL FOR DEBUGING for J2.5 (do not remove commented code) //$diff_arr = array_diff_assoc ( $data, $post); //echo "<pre>"; print_r($diff_arr); jexit(); // ******************************************************************************** // PERFORM ACCESS CHECKS, NOTE: we need to check access again, despite having // checked them on edit form load, because user may have tampered with the form ... // ******************************************************************************** $type_id = (int) @ $post['type_id']; // Typecast to int, (already done for J2.5 via validating) if ( !$isnew && $model->get('type_id') == $type_id ) { // Existing item with Type not being ALTERED, content type can be maintained regardless of privilege $canCreateType = true; } else { // New item or existing item with Type is being ALTERED, check privilege to create items of this type $canCreateType = $model->canCreateType( array($type_id), true, $types ); } // **************************************************************** // Calculate user's privileges on current content item // ... canPublish IS RECALCULATED after saving, maybe comment out ? // **************************************************************** if (!$isnew) { if (FLEXI_J16GE) { $asset = 'com_content.article.' . $model->get('id'); $canPublish = $user->authorise('core.edit.state', $asset) || ($user->authorise('core.edit.state.own', $asset) && $model->get('created_by') == $user->get('id')); $canEdit = $user->authorise('core.edit', $asset) || ($user->authorise('core.edit.own', $asset) && $model->get('created_by') == $user->get('id')); // ALTERNATIVE 1 //$canEdit = $model->getItemAccess()->get('access-edit'); // includes privileges edit and edit-own // ALTERNATIVE 2 //$rights = FlexicontentHelperPerm::checkAllItemAccess($user->get('id'), 'item', $model->get('id')); //$canEdit = in_array('edit', $rights) || (in_array('edit.own', $rights) && $model->get('created_by') == $user->get('id')) ; } else if ($user->gid >= 25) { $canPublish = true; $canEdit = true; } else if (FLEXI_ACCESS) { $rights = FAccess::checkAllItemAccess('com_content', 'users', $user->gmid, $model->get('id'), $model->get('catid')); $canPublish = in_array('publish', $rights) || (in_array('publishown', $rights) && $model->get('created_by') == $user->get('id')) ; $canEdit = in_array('edit', $rights) || (in_array('editown', $rights) && $model->get('created_by') == $user->get('id')) ; } else { $canPublish = $user->authorize('com_content', 'publish', 'content', 'all'); $canEdit = $user->authorize('com_content', 'edit', 'content', 'all') || ($user->authorize('com_content', 'edit', 'content', 'own') && $model->get('created_by') == $user->get('id')); //$canPublish = ($user->gid >= 21); // At least J1.5 Publisher //$canEdit = ($user->gid >= 20); // At least J1.5 Editor } if ( !$canEdit ) { // No edit privilege, check if item is editable till logoff if ($session->has('rendered_uneditable', 'flexicontent')) { $rendered_uneditable = $session->get('rendered_uneditable', array(),'flexicontent'); $canEdit = isset($rendered_uneditable[$model->get('id')]) && $rendered_uneditable[$model->get('id')]; } } } else { if (FLEXI_J16GE) { $canAdd = $model->getItemAccess()->get('access-create'); // includes check of creating in at least one category $not_authorised = !$canAdd; $canPublish = $user->authorise('core.edit.state', 'com_flexicontent') || $user->authorise('core.edit.state.own', 'com_flexicontent'); } else if ($user->gid >= 25) { $canAdd = 1; } else if (FLEXI_ACCESS) { $canAdd = FAccess::checkUserElementsAccess($user->gmid, 'submit'); $canAdd = @$canAdd['content'] || @$canAdd['category']; $canPublishAll = FAccess::checkAllContentAccess('com_content','publish','users',$user->gmid,'content','all'); $canPublishOwnAll = FAccess::checkAllContentAccess('com_content','publishown','users',$user->gmid,'content','all'); $canPublish = ($user->gid < 25) ? $canPublishAll || $canPublishOwnAll : 1; } else { $canAdd = $user->authorize('com_content', 'add', 'content', 'all'); //$canAdd = ($user->gid >= 19); // At least J1.5 Author $not_authorised = ! $canAdd; $canPublish = ($user->gid >= 21); } if ( $allowunauthorize ) { $canAdd = true; $canCreateType = true; } } // ... we use some strings from administrator part // load english language file for 'com_flexicontent' component then override with current language file JFactory::getLanguage()->load('com_flexicontent', JPATH_ADMINISTRATOR, 'en-GB', true); JFactory::getLanguage()->load('com_flexicontent', JPATH_ADMINISTRATOR, null, true); // Check for new content if ( ($isnew && !$canAdd) || (!$isnew && !$canEdit)) { $msg = JText::_( 'FLEXI_ALERTNOTAUTH' ); if (FLEXI_J16GE) throw new Exception($msg, 403); else JError::raiseError(403, $msg); } if ( !$canCreateType ) { $msg = isset($types[$type_id]) ? JText::sprintf( 'FLEXI_NO_ACCESS_CREATE_CONTENT_OF_TYPE', JText::_($types[$type_id]->name) ) : ' Content Type '.$type_id.' was not found OR is not published'; if (FLEXI_J16GE) throw new Exception($msg, 403); else JError::raiseError(403, $msg); return; } // Get "BEFORE SAVE" categories for information mail $before_cats = array(); if ( !$isnew ) { $query = 'SELECT DISTINCT c.id, c.title FROM #__categories AS c' . ' JOIN #__flexicontent_cats_item_relations AS rel ON rel.catid = c.id' . ' WHERE rel.itemid = '.(int) $model->get('id'); $db->setQuery( $query ); $before_cats = $db->loadObjectList('id'); $before_maincat = $model->get('catid'); $original_item = $model->getItem($post['id'], $check_view_access=false, $no_cache=true, $force_version=0); } // **************************************** // Try to store the form data into the item // **************************************** if ( ! $model->store($post) ) { // Set error message about saving failed, and also the reason (=model's error message) $msg = JText::_( 'FLEXI_ERROR_STORING_ITEM' ); JError::raiseWarning( 500, $msg .": " . $model->getError() ); // Since an error occured, check if (a) the item is new and (b) was not created if ($isnew && !$model->get('id')) { $msg = ''; $link = 'index.php?option=com_flexicontent&'.$ctrl_task.'add&id=0&typeid='.$type_id.'&'. (FLEXI_J30GE ? JSession::getFormToken() : JUtility::getToken()) .'=1'; $this->setRedirect($link, $msg); } else { $msg = ''; $link = 'index.php?option=com_flexicontent&'.$ctrl_task.'edit&id='.$model->get('id').'&'. (FLEXI_J30GE ? JSession::getFormToken() : JUtility::getToken()) .'=1'; $this->setRedirect($link, $msg); } // Saving has failed check-in and return, (above redirection will be used) $model->checkin(); return; } // ************************************************** // Check in model and get item id in case of new item // ************************************************** $model->checkin(); $post['id'] = $isnew ? (int) $model->get('id') : $post['id']; // Get items marked as newly submitted $newly_submitted = $session->get('newly_submitted', array(), 'flexicontent'); if ($isnew) { // Mark item as newly submitted, to allow to a proper "THANKS" message after final save & close operation (since user may have clicked add instead of add & close) $newly_submitted[$model->get('id')] = 1; $session->set('newly_submitted', $newly_submitted, 'flexicontent'); } $newly_submitted_item = @ $newly_submitted[$model->get('id')]; // *********************************************************************************************************** // Get newly saved -latest- version (store task gets latest) of the item, and also calculate publish privelege // *********************************************************************************************************** $item = $model->getItem($post['id'], $check_view_access=false, $no_cache=true, $force_version=-1); $canPublish = $model->canEditState( $item, $check_cat_perm=true ); // ******************************************************************************************** // Use session to detect multiple item saves to avoid sending notification EMAIL multiple times // ******************************************************************************************** $is_first_save = true; if ($session->has('saved_fcitems', 'flexicontent')) { $saved_fcitems = $session->get('saved_fcitems', array(), 'flexicontent'); $is_first_save = $isnew ? true : !isset($saved_fcitems[$model->get('id')]); } // Add item to saved items of the corresponding session array $saved_fcitems[$model->get('id')] = $timestamp = time(); // Current time as seconds since Unix epoc; $session->set('saved_fcitems', $saved_fcitems, 'flexicontent'); // ******************************************** // Get categories added / removed from the item // ******************************************** $query = 'SELECT DISTINCT c.id, c.title FROM #__categories AS c' . ' JOIN #__flexicontent_cats_item_relations AS rel ON rel.catid = c.id' . ' WHERE rel.itemid = '.(int) $model->get('id'); $db->setQuery( $query ); $after_cats = $db->loadObjectList('id'); if ( !$isnew ) { $cats_added_ids = array_diff(array_keys($after_cats), array_keys($before_cats)); foreach($cats_added_ids as $cats_added_id) { $cats_added_titles[] = $after_cats[$cats_added_id]->title; } $cats_removed_ids = array_diff(array_keys($before_cats), array_keys($after_cats)); foreach($cats_removed_ids as $cats_removed_id) { $cats_removed_titles[] = $before_cats[$cats_removed_id]->title; } $cats_altered = count($cats_added_ids) + count($cats_removed_ids); $after_maincat = $model->get('catid'); } // ******************************************************************************************************************* // We need to get emails to notify, from Global/item's Content Type parameters -AND- from item's categories parameters // ******************************************************************************************************************* $notify_emails = array(); if ( $is_first_save || $cats_altered || $params->get('nf_enable_debug',0) ) { // Get needed flags regarding the saved items $approve_version = 2; $pending_approval_state = -3; $draft_state = -4; $current_version = FLEXIUtilities::getCurrentVersions($item->id, true); // Get current item version $last_version = FLEXIUtilities::getLastVersions($item->id, true); // Get last version (=latest one saved, highest version id), // $post variables vstate & state may have been (a) tampered in the form, and/or (b) altered by save procedure so better not use them $needs_version_reviewal = !$isnew && ($last_version > $current_version) && !$canPublish; $needs_publication_approval = $isnew && ($item->state == $pending_approval_state) && !$canPublish; $draft_from_non_publisher = $item->state==$draft_state && !$canPublish; if ($draft_from_non_publisher) { // Suppress notifications for draft-state items (new or existing ones), for these each author will publication approval manually via a button $nConf = false; } else { // Get notifications configuration and select appropriate emails for current saving case $nConf = $model->getNotificationsConf($params); //echo "<pre>"; print_r($nConf); "</pre>"; } if ($nConf) { $states_notify_new = $params->get('states_notify_new', array(1,0,(FLEXI_J16GE ? 2:-1),-3,-4,-5)); if ( empty($states_notify_new) ) $states_notify_new = array(); else if ( ! is_array($states_notify_new) ) $states_notify_new = !FLEXI_J16GE ? array($states_notify_new) : explode("|", $states_notify_new); $states_notify_existing = $params->get('states_notify_existing', array(1,0,(FLEXI_J16GE ? 2:-1),-3,-4,-5)); if ( empty($states_notify_existing) ) $states_notify_existing = array(); else if ( ! is_array($states_notify_existing) ) $states_notify_existing = !FLEXI_J16GE ? array($states_notify_existing) : explode("|", $states_notify_existing); $n_state_ok = in_array($item->state, $states_notify_new); $e_state_ok = in_array($item->state, $states_notify_existing); if ($needs_publication_approval) $notify_emails = $nConf->emails->notify_new_pending; else if ($isnew && $n_state_ok) $notify_emails = $nConf->emails->notify_new; else if ($isnew) $notify_emails = array(); else if ($needs_version_reviewal) $notify_emails = $nConf->emails->notify_existing_reviewal; else if (!$isnew && $e_state_ok) $notify_emails = $nConf->emails->notify_existing; else if (!$isnew) $notify_emails = array(); if ($needs_publication_approval) $notify_text = $params->get('text_notify_new_pending'); else if ($isnew) $notify_text = $params->get('text_notify_new'); else if ($needs_version_reviewal) $notify_text = $params->get('text_notify_existing_reviewal'); else if (!$isnew) $notify_text = $params->get('text_notify_existing'); //print_r($notify_emails); jexit(); } } // ********************************************************************************************************************* // If there are emails to notify for current saving case, then send the notifications emails, but // ********************************************************************************************************************* if ( !empty($notify_emails) && count($notify_emails) ) { $notify_vars = new stdClass(); $notify_vars->needs_version_reviewal = $needs_version_reviewal; $notify_vars->needs_publication_approval = $needs_publication_approval; $notify_vars->isnew = $isnew; $notify_vars->notify_emails = $notify_emails; $notify_vars->notify_text = $notify_text; $notify_vars->before_cats = $before_cats; $notify_vars->after_cats = $after_cats; $notify_vars->original_item = @ $original_item; $model->sendNotificationEmails($notify_vars, $params, $manual_approval_request=0); } // *************************************************** // CLEAN THE CACHE so that our changes appear realtime // *************************************************** if (FLEXI_J16GE) { $cache = FLEXIUtilities::getCache($group='', 0); $cache->clean('com_flexicontent_items'); $cache->clean('com_flexicontent_filters'); $cache = FLEXIUtilities::getCache($group='', 1); $cache->clean('com_flexicontent_items'); $cache->clean('com_flexicontent_filters'); } else { $itemcache = JFactory::getCache('com_flexicontent_items'); $itemcache->clean(); $filtercache = JFactory::getCache('com_flexicontent_filters'); $filtercache->clean(); } // **************************************************************************************************************************** // Recalculate EDIT PRIVILEGE of new item. Reason for needing to do this is because we can have create permission in a category // and thus being able to set this category as item's main category, but then have no edit/editown permission for this category // **************************************************************************************************************************** if (FLEXI_J16GE) { $asset = 'com_content.article.' . $model->get('id'); $canEdit = $user->authorise('core.edit', $asset) || ($user->authorise('core.edit.own', $asset) && $model->get('created_by') == $user->get('id')); // ALTERNATIVE 1 //$canEdit = $model->getItemAccess()->get('access-edit'); // includes privileges edit and edit-own // ALTERNATIVE 2 //$rights = FlexicontentHelperPerm::checkAllItemAccess($user->get('id'), 'item', $model->get('id')); //$canEdit = in_array('edit', $rights) || (in_array('edit.own', $rights) && $model->get('created_by') == $user->get('id')) ; } else if (FLEXI_ACCESS && $user->gid < 25) { $rights = FAccess::checkAllItemAccess('com_content', 'users', $user->gmid, $model->get('id'), $model->get('catid')); $canEdit = in_array('edit', $rights) || (in_array('editown', $rights) && $model->get('created_by') == $user->get('id')) ; } else { // This is meaningful when executed in frontend, since all backend users (managers and above) can edit items $canEdit = $user->authorize('com_content', 'edit', 'content', 'all') || ($user->authorize('com_content', 'edit', 'content', 'own') && $model->get('created_by') == $user->get('id')); } // ******************************************************************************************************* // Check if user can not edit item further (due to changed main category, without edit/editown permission) // ******************************************************************************************************* if (!$canEdit) { if ($task=='apply') { // APPLY TASK: Temporarily set item to be editable till closing it $rendered_uneditable = $session->get('rendered_uneditable', array(),'flexicontent'); $rendered_uneditable[$model->get('id')] = 1; $session->set('rendered_uneditable', $rendered_uneditable, 'flexicontent'); $canEdit = 1; } else if ( $newly_submitted_item ) { // NEW ITEM: Do not use editable till logoff behaviour // ALSO: Clear editable FLAG set in the case that 'apply' button was used during new item creation if ( !$params->get('items_session_editable', 0) ) { $rendered_uneditable = $session->get('rendered_uneditable', array(),'flexicontent'); if ( isset($rendered_uneditable[$model->get('id')]) ) { unset( $rendered_uneditable[$model->get('id')] ); $session->set('rendered_uneditable', $rendered_uneditable, 'flexicontent'); } } } else { // EXISTING ITEM: (if enabled) Use the editable till logoff behaviour if ( $params->get('items_session_editable', 0) ) { // Set notice for existing item being editable till logoff JError::raiseNotice( 403, JText::_( 'FLEXI_CANNOT_EDIT_AFTER_LOGOFF' ) ); // Allow item to be editable till logoff $rendered_uneditable = $session->get('rendered_uneditable', array(),'flexicontent'); $rendered_uneditable[$model->get('id')] = 1; $session->set('rendered_uneditable', $rendered_uneditable, 'flexicontent'); $canEdit = 1; } } // Set notice about saving an item that cannot be changed further if ( !$canEdit ) { $app->enqueueMessage(JText::_( 'FLEXI_CANNOT_MAKE_FURTHER_CHANGES_TO_CONTENT' ), 'message' ); } } // **************************************************************** // Check for new Content Item is being closed, and clear some flags // **************************************************************** if ($task!='apply' && $newly_submitted_item ) { // Clear item from being marked as newly submitted unset($newly_submitted[$model->get('id')]); $session->set('newly_submitted', $newly_submitted, 'flexicontent'); // The 'apply' task may set 'editable till logoff' FLAG ... // CLEAR IT, since NEW content this is meant to be used temporarily if ( !$params->get('items_session_editable', 0) ) { $rendered_uneditable = $session->get('rendered_uneditable', array(),'flexicontent'); if ( isset($rendered_uneditable[$model->get('id')]) ) { unset( $rendered_uneditable[$model->get('id')] ); $session->set('rendered_uneditable', $rendered_uneditable, 'flexicontent'); } } } // **************************************** // Saving is done, decide where to redirect // **************************************** // REDIRECT CASE FOR APPLYING: Save and reload the item edit form if ($task=='apply') { $msg = JText::_( 'FLEXI_ITEM_SAVED' ); // Create the URL global $globalcats; $Itemid = JRequest::getInt('Itemid', 0); // maintain current menu item if this was given $item_url = JRoute::_(FlexicontentHelperRoute::getItemRoute($item->id.':'.$item->alias, $globalcats[$item->catid]->slug, $Itemid)); $link = $item_url .(strstr($item_url, '?') ? '&' : '?').'task=edit' ; // Important pass referer back to avoid making the form itself the referer // but also check that referer URL is 'safe' (allowed) , e.g. not an offsite URL, otherwise set referer to HOME page $referer = JRequest::getString('referer', JURI::base(), 'post'); if ( ! flexicontent_html::is_safe_url($referer) ) $referer = JURI::base(); $return = '&return='.base64_encode( $referer ); $link .= $return; } // REDIRECT CASES FOR SAVING else { // REDIRECT CASE: Return to a custom page after creating a new item (e.g. a thanks page) if ( $newly_submitted_item && $submit_redirect_url_fe ) { $link = $submit_redirect_url_fe; $msg = JText::_( 'FLEXI_ITEM_SAVED' ); } // REDIRECT CASE: Save and preview the latest version else if ($task=='save_a_preview') { $msg = JText::_( 'FLEXI_ITEM_SAVED' ); $link = JRoute::_(FlexicontentHelperRoute::getItemRoute($model->_item->id.':'.$model->_item->alias, $model->_item->catid, 0, $model->_item).'&preview=1', false); } // REDIRECT CASE: Return to the form 's referer (previous page) after item saving else { $msg = $newly_submitted_item ? JText::_( 'FLEXI_THANKS_SUBMISSION' ) : JText::_( 'FLEXI_ITEM_SAVED' ); // Check that referer URL is 'safe' (allowed) , e.g. not an offsite URL, otherwise for returning to HOME page $link = JRequest::getString('referer', JURI::base(), 'post'); if ( ! flexicontent_html::is_safe_url($link) ) { if ( $dolog ) JFactory::getApplication()->enqueueMessage( 'refused redirection to possible unsafe URL: '.$link, 'notice' ); $link = JURI::base(); } } } $this->setRedirect($link, $msg); }
function save_import() { // Check for request forgeries //JRequest::checkToken() or jexit( 'Invalid Token' ); //mara $arr_countries = array('AL' => 'Albania', 'AM' => 'Armenia' , 'ARG' =>'Argentina' , 'AU' => 'Australia' , 'AUT' => 'Austria' , 'AZ' =>'Azerbaidjan' , 'BEL' => 'Belgium' , 'BGD' => 'Bangladesh' , 'BLG' => 'Bulgaria' , 'BLR' => 'Belarus' , 'BOS' => 'Bosnia-Herzegovina' , 'BRA' => 'Brazil' , 'CAN' => 'Canada' , 'CB' => 'Cuba' , 'CHE' => 'Switzerland' , 'CHI' => 'China' , 'CHL' => 'Chile' , 'CS' => 'Czech Republic' , 'DEU' => 'Germany' , 'DNK' => 'Denmark' , 'EGP' => 'Egypt' , 'EST' => 'Estonia' , 'FIN' => 'Finland' , 'FRA' => 'France' , 'GBR' => 'Great Britain' , 'GBRUSA' => 'Great Britain' , 'GEO' => 'Georgia' , 'GR' => 'Greece' , 'HK' => 'Hong Kong' , 'HOR' => 'Croatia' , 'HUN' => 'Hungary' , 'IDZ' => 'Indonesia' , 'IND' => 'India' , 'IOR' => 'Jordan' , 'IRA' => 'Iran' , 'IRL' => 'Ireland' , 'ISL' => 'Iceland' , 'ISR' => 'Israel' , 'ITA' => 'Italy' , 'JPN' => 'Japan' , 'KAZ' => 'Kazakhstan' , 'KGZ' => 'Kyrgyzstan' , 'KIP' => 'Cyprus' , 'LAT' => 'Latvia' , 'LIT' => 'Lithuania' , 'LUX' => 'Luxembourg' , 'MAK' => 'Macedonia' , 'ME' => 'Montenegro' , 'MEK' => 'Mexico' , 'MLT' => 'Malta' , 'MOL' => 'Moldavia' , 'MON' => 'Monaco' , 'NID' => 'Netherlands' , 'NOR' => 'Norway' , 'PAK' => 'Pakistan' , 'POL' => 'Poland' , 'PORT' => 'Portugal' , 'PR' => 'Puerto Rico' , 'PS' => 'Palestinian Territory' , 'RS' => 'Serbia' , 'RUM' => 'Romania' , 'RUS' => 'Russian Federation' , 'SA' => 'Saudi Arabia' , 'SCH' => 'Serbia' , 'SGP' => 'Singapore' , 'SHE' => 'Switzerland' , 'SKO' => 'South Korea' , 'SLO' => 'Slovenia' , 'SLR' => 'Slovak Republic' , 'SM' => 'San Marino' , 'SPN' => 'Spain' , 'SWE' => 'Sweden' , 'SYR' => 'Syria' , 'TA' => 'Thailand' , 'TUR' => 'Turkey' , 'UAR' => 'South Africa' , 'UGS' => 'Serbia' , 'UKR' => 'Ukraine' , 'unk' => 'Unknown' , 'USA' => 'United States' , 'USAFRA' => 'United States' , 'Uzb' => 'Uzbekistan' , 'VTN' => 'Vietnam'); mysql_connect('localhost', 'root', 'staSPE8e'); mysql_select_db('vidal'); mysql_query("SET NAMES utf8"); $query = "SELECT pa.ATCCode,m.LatName,n.NozologyCode,Document.DocumentID," ."Document.RusName,Document.EngName,Document.CompiledComposition,Document.PhInfluence,Document.PhKinetics," ."Document.Dosage,Document.OverDosage,Document.Interaction,Document.Lactation,Document.SideEffects," ."Document.StorageCondition,Document.Indication,Document.ContraIndication,Document.SpecialInstruction " . "FROM Document" ." LEFT JOIN Document_IndicNozology as n ON Document.DocumentID = n.DocumentID" ." LEFT JOIN Molecule_Document as md ON md.DocumentID = Document.DocumentID" ." LEFT JOIN Molecule as m ON m.MoleculeID = md.MoleculeID" ." LEFT JOIN Product_Document as pd ON pd.DocumentID = Document.DocumentID" ." LEFT JOIN Product_ATC as pa ON pd.ProductID = pa.ProductID" ." GROUP BY Document.DocumentID"; $result = mysql_query($query) or die(mysql_error()); while($all = mysql_fetch_array($result)){ // Initialize variables $app = JFactory::getApplication(); $db = JFactory::getDBO(); $user = JFactory::getUser(); $menu = $app->getMenu()->getActive(); $config = JFactory::getConfig(); $session = JFactory::getSession(); $task = JRequest::getVar('task'); $model = $this->getModel(FLEXI_ITEMVIEW); $isnew = !$model->getId(); $ctrl_task = FLEXI_J16GE ? 'task=items.' : 'controller=items&task='; $fc_params = JComponentHelper::getParams( 'com_flexicontent' ); $dolog = $fc_params->get('print_logging_info'); // Get the COMPONENT only parameters $comp_params = JComponentHelper::getComponent('com_flexicontent')->params; $params = FLEXI_J16GE ? clone ($comp_params) : new JParameter( $comp_params ); // clone( JComponentHelper::getParams('com_flexicontent') ); // Merge the type parameters $tparams = $model->getTypeparams(); $tparams = FLEXI_J16GE ? new JRegistry($tparams) : new JParameter($tparams); $params->merge($tparams); // Merge the menu parameters if ($menu) { $menu_params = FLEXI_J16GE ? $menu->params : new JParameter($menu->params); $params->merge($menu_params); } // Get needed parameters $submit_redirect_url_fe = $params->get('submit_redirect_url_fe', ''); $allowunauthorize = $params->get('allowunauthorize', 0); $data = array(); $data['title'] = $all['RusName']; //content $data['text'] = $all['CompiledComposition'].$all['PhInfluence'].$all['PhKinetics'].$all['Dosage'].$all['OverDosage'].$all['Interaction'].$all['Lactation'].$all['SideEffects'].$all['StorageCondition'].$all['Indication'].$all['ContraIndication'].$all['SpecialInstruction']; $data['state'] = 1; $data['catid'] = 45; $data['type_id'] = 2; $data['id'] = 0; //insert into content //flexicontent_fields_item_relations //15 field RusName EngName //19 field Zabolev $zab = ''; if($all['NozologyCode']){ $tmp = $all['NozologyCode']; $zab_cif = substr($tmp,1,2); $alpha = substr($tmp,0,1); switch($alpha){ case 'A' : $zab = 'A00–B99'; break; case 'B' : $zab = 'A00–B99';break; case 'C' : $zab = 'C00–D48';break; case 'D' : $zab = $zab_cif <= 48 ? 'C00–D48' : 'D50–D89';break; case 'E' : $zab = 'E00–E90';break; case 'F' : $zab = 'F00–F99';break; case 'G' : $zab = 'G00–G99';break; case 'H' : $zab = $zab_cif <= 59 ? 'H00–H59' : 'H60–H95';break; case 'I' : $zab = 'I00–I99';break; case 'J' : $zab = 'J00–J99';break; case 'K' : $zab = 'K00–K93';break; case 'L' : $zab = 'L00–L99';break; case 'M' : $zab = 'M00–M99';break; case 'N' : $zab = 'N00–N99';break; case 'O' : $zab = 'O00–O99';break; case 'P' : $zab = 'P00–P96'; break; case 'R' : $zab = 'R00–R99'; break; case 'S' : $zab = 'S00–T98'; break; case 'V' : $zab = 'V01–Y98';break; case 'Z' : $zab = 'Z00–Z99';break; case 'U' : $zab = 'U00–U99'; break; default: $zab = ''; } } $custom = array(); $custom['zabolevanie'] = $zab; $custom['field24'] = $all['ATCCode']; /*$custom['field24_1'] = ''; $custom['field24_2'] = ''; $custom['field24_3'] = ''; $custom['field24_4'] = ''; $custom['field24_5'] = '';*/ $custom['preparat'][0] = addslashes($all['RusName']); $custom['preparat'][1] = addslashes($all['EngName']); $custom['field22'][0] = addslashes($all['LatName']); $query = "SELECT p.DateOfCloseRegistration, p.RegistrationNumber, p.Composition, p.ZipInfo, " ." c.LocalName, c.CountryCode " . "FROM Product as p" ." JOIN Product_Company as pc ON pc.ProductID = p.ProductID" ." JOIN Company as c ON c.CompanyID = pc.CompanyID" ." JOIN Product_Document d ON d.ProductID = p.ProductID" ." WHERE d.DocumentID = ".$all['DocumentID']; $result1 = mysql_query($query) or die(mysql_error()); $field_pr = array(); $z = 0; while($proizv = mysql_fetch_array($result1)){ if(isset($arr_countries[$proizv['CountryCode']])){ $custom['field21'][0]['country'][$z] = addslashes($arr_countries[$proizv['CountryCode']]); $custom['field21'][0]['naimen'][$z] = addslashes($proizv['LocalName']);//."<br />".$proizv['Composition']); $custom['field21'][0]['vypusk'][$z] = addslashes($proizv['ZipInfo']); $custom['field21'][0]['reg'][$z] = addslashes($proizv['RegistrationNumber']); $custom['field21'][0]['date'][$z] = addslashes($proizv['DateOfCloseRegistration']); } $z++; } // ********************* // Get data from request // ********************* if (FLEXI_J16GE) { // Retrieve form data these are subject to basic filtering // $data = JRequest::getVar('jform', array(), 'post', 'array'); // Core Fields and and item Parameters // $custom = JRequest::getVar('custom', array(), 'post', 'array'); // Custom Fields $jfdata = JRequest::getVar('jfdata', array(), 'post', 'array'); // Joomfish Data if ( ! @ $data['rules'] ) $data['rules'] = array(); } else { // Retrieve form data these are subject to basic filtering $data = JRequest::get( 'post' ); // Core & Custom Fields and item Parameters } // Set data id into model in case not already set ? $model->setId((int) $data['id']); // ************************************* // ENFORCE can change category ACL perms // ************************************* $perms = FlexicontentHelperPerm::getPerm(); // Per content type change category permissions if (FLEXI_J16GE) { $current_type_id = ($isnew || !$model->get('type_id')) ? $data['type_id'] : $model->get('type_id'); // GET current (existing/old) item TYPE ID $CanChangeFeatCat = $user->authorise('flexicontent.change.cat.feat', 'com_flexicontent.type.' . $current_type_id); $CanChangeSecCat = $user->authorise('flexicontent.change.cat.sec', 'com_flexicontent.type.' . $current_type_id); $CanChangeCat = $user->authorise('flexicontent.change.cat', 'com_flexicontent.type.' . $current_type_id); } else { $CanChangeFeatCat = 1; $CanChangeSecCat = 1; $CanChangeCat = 1; } $featured_cats_parent = $params->get('featured_cats_parent', 0); $featured_cats = array(); $enable_featured_cid_selector = $perms->MultiCat && $CanChangeFeatCat; $enable_cid_selector = $perms->MultiCat && $CanChangeSecCat; $enable_catid_selector = ($isnew && !$tparams->get('catid_default')) || (!$isnew && !$model->get('catid')) || $CanChangeCat; // Enforce maintaining featured categories $featured_cats_parent = $params->get('featured_cats_parent', 0); $featured_cats = array(); if ( $featured_cats_parent && !$enable_featured_cid_selector ) { $featured_tree = flexicontent_cats::getCategoriesTree($published_only=1, $parent_id=$featured_cats_parent, $depth_limit=0); $featured_cid = array(); if (!$isnew) { foreach($model->get('categories') as $item_cat) if (isset($featured_tree[$item_cat])) $featured_cid[] = $item_cat; } $data['featured_cid'] = $featured_cid; } // Enforce maintaining secondary categories if (!$enable_cid_selector) { if ($isnew) { $data['cid'] = $tparams->get('cid_default'); } else if ( isset($featured_cid) ) { $featured_cid_arr = array_flip($featured_cid); $sec_cid = array(); foreach($model->get('cats') as $item_cat) if (!isset($featured_cid_arr[$item_cat])) $sec_cid[] = $item_cat; $data['cid'] = $sec_cid; } else { $data['cid'] = $model->get('cats'); } } if (!$enable_catid_selector) { if ($isnew && $tparams->get('catid_default')) $data['catid'] = $tparams->get('catid_default'); else if ($model->get('catid')) $data['catid'] = $model->get('catid'); } // ************************** // Basic Form data validation // ************************** if (FLEXI_J16GE) { // *** MANUALLY CHECK CAPTCHA *** $use_captcha = $params->get('use_captcha', 1); // 1 for guests, 2 for any user $captcha_formop = $params->get('captcha_formop', 0); // 0 for submit, 1 for submit/edit (aka always) $is_submitop = ((int) $data['id']) == 0; $display_captcha = $use_captcha >= 2 || ( $use_captcha == 1 && $user->guest ); $display_captcha = $display_captcha && ( $is_submitop || $captcha_formop); // for submit operation we do not need to check 'captcha_formop' ... if ($display_captcha) { // Try to force the use of recaptcha plugin JFactory::getConfig()->set('captcha', 'recaptcha'); if ( $app->getCfg('captcha') == 'recaptcha' && JPluginHelper::isEnabled('captcha', 'recaptcha') ) { JPluginHelper::importPlugin('captcha'); $dispatcher = JDispatcher::getInstance(); $result = $dispatcher->trigger('onCheckAnswer', JRequest::getString('recaptcha_response_field')); if (!$result[0]) { $errmsg = JText::_('FLEXI_CAPTCHA_FAILED'); $errmsg .= ' '.JText::_('FLEXI_MUST_REFILL_SOME_FIELDS'); echo "<script>alert('".$errmsg."');"; echo "window.history.back();"; echo "</script>"; jexit(); } } } // Validate Form data for core fields and for parameters $form = $model->getForm(); // Do not pass any data we only want the form object in order to validate the data and not create a filled-in form $post = $model->validate($form, $data); // Check for validation error if (!$post) { // Get the validation messages. $errors = $form->getErrors(); // Push up to three validation messages out to the user. for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) { if ($errors[$i] instanceof Exception) $app->enqueueMessage($errors[$i]->getMessage(), 'notice'); else $app->enqueueMessage($errors[$i], 'notice'); } // Save the jform data in the session. $app->setUserState($form->option.'.edit.'.$form->context.'.data', $data); // Save the custom fields data in the session. $app->setUserState($form->option.'.edit.'.$form->context.'.custom', $custom); // Redirect back to the registration form. $this->setRedirect( $_SERVER['HTTP_REFERER'] ); return false; //die('error'); } /*if (!$post) { //JError::raiseWarning( 500, "Error while validating data: " . $model->getError() ); echo "Error while validating data: " . $model->getError(); echo '<span class="fc_return_msg">'.JText::sprintf('FLEXI_CLICK_HERE_TO_RETURN', '"JavaScript:window.history.back();"').'</span>'; jexit(); }*/ // Some values need to be assigned after validation $post['attribs'] = @$data['attribs']; // Workaround for item's template parameters being clear by validation since they are not present in item.xml $post['custom'] = & $custom; // Assign array of custom field values, they are in the 'custom' form array instead of jform $post['jfdata'] = & $jfdata; // Assign array of Joomfish field values, they are in the 'jfdata' form array instead of jform // Assign template parameters of the select ilayout as an sub-array (the DB model will handle the merging of parameters) $ilayout = @ $data['attribs']['ilayout']; // normal not be set if frontend template editing is not shown if( $ilayout && !empty($data['layouts'][$ilayout]) ) $post['attribs']['layouts'] = $data['layouts']; //echo "<pre>"; print_r($post['attribs']); exit; } else { $post = $data; // Some values need to be assigned after validation $post['text'] = JRequest::getVar( 'text', '', 'post', 'string', JREQUEST_ALLOWRAW ); // Workaround for allowing raw text field // Assign template parameters of the select ilayout as an sub-array (the DB model will handle the merging of parameters) $ilayout = @ $post['params']['ilayout']; // normal not be set if frontend template editing is not shown if( $ilayout && !empty($post['layouts'][$ilayout]) ) $post['params']['layouts'] = $post['layouts']; //echo "<pre>"; print_r($post['params']); exit; } // USEFULL FOR DEBUGING for J2.5 (do not remove commented code) //$diff_arr = array_diff_assoc ( $data, $post); //echo "<pre>"; print_r($diff_arr); jexit(); // ******************************************************************************** // PERFORM ACCESS CHECKS, NOTE: we need to check access again, despite having // checked them on edit form load, because user may have tampered with the form ... // ******************************************************************************** $type_id = (int) @ $post['type_id']; // Typecast to int, (already done for J2.5 via validating) if ( !$isnew && $model->get('type_id') == $type_id ) { // Existing item with Type not being ALTERED, content type can be maintained regardless of privilege $canCreateType = true; } else { // New item or existing item with Type is being ALTERED, check privilege to create items of this type $canCreateType = $model->canCreateType( array($type_id), true, $types ); } // **************************************************************** // Calculate user's privileges on current content item // ... canPublish IS RECALCULATED after saving, maybe comment out ? // **************************************************************** if (!$isnew) { if (FLEXI_J16GE) { $asset = 'com_content.article.' . $model->get('id'); $canPublish = $user->authorise('core.edit.state', $asset) || ($user->authorise('core.edit.state.own', $asset) && $model->get('created_by') == $user->get('id')); $canEdit = $user->authorise('core.edit', $asset) || ($user->authorise('core.edit.own', $asset) && $model->get('created_by') == $user->get('id')); // ALTERNATIVE 1 //$canEdit = $model->getItemAccess()->get('access-edit'); // includes privileges edit and edit-own // ALTERNATIVE 2 //$rights = FlexicontentHelperPerm::checkAllItemAccess($user->get('id'), 'item', $model->get('id')); //$canEdit = in_array('edit', $rights) || (in_array('edit.own', $rights) && $model->get('created_by') == $user->get('id')) ; } else if ($user->gid >= 25) { $canPublish = true; $canEdit = true; } else if (FLEXI_ACCESS) { $rights = FAccess::checkAllItemAccess('com_content', 'users', $user->gmid, $model->get('id'), $model->get('catid')); $canPublish = in_array('publish', $rights) || (in_array('publishown', $rights) && $model->get('created_by') == $user->get('id')) ; $canEdit = in_array('edit', $rights) || (in_array('editown', $rights) && $model->get('created_by') == $user->get('id')) ; } else { $canPublish = $user->authorize('com_content', 'publish', 'content', 'all'); $canEdit = $user->authorize('com_content', 'edit', 'content', 'all') || ($user->authorize('com_content', 'edit', 'content', 'own') && $model->get('created_by') == $user->get('id')); //$canPublish = ($user->gid >= 21); // At least J1.5 Publisher //$canEdit = ($user->gid >= 20); // At least J1.5 Editor } if ( !$canEdit ) { // No edit privilege, check if item is editable till logoff if ($session->has('rendered_uneditable', 'flexicontent')) { $rendered_uneditable = $session->get('rendered_uneditable', array(),'flexicontent'); $canEdit = isset($rendered_uneditable[$model->get('id')]) && $rendered_uneditable[$model->get('id')]; } } } else { if (FLEXI_J16GE) { $canAdd = $model->getItemAccess()->get('access-create'); // includes check of creating in at least one category $not_authorised = !$canAdd; $canPublish = $user->authorise('core.edit.state', 'com_flexicontent') || $user->authorise('core.edit.state.own', 'com_flexicontent'); } else if ($user->gid >= 25) { $canAdd = 1; } else if (FLEXI_ACCESS) { $canAdd = FAccess::checkUserElementsAccess($user->gmid, 'submit'); $canAdd = @$canAdd['content'] || @$canAdd['category']; $canPublishAll = FAccess::checkAllContentAccess('com_content','publish','users',$user->gmid,'content','all'); $canPublishOwnAll = FAccess::checkAllContentAccess('com_content','publishown','users',$user->gmid,'content','all'); $canPublish = ($user->gid < 25) ? $canPublishAll || $canPublishOwnAll : 1; } else { $canAdd = $user->authorize('com_content', 'add', 'content', 'all'); //$canAdd = ($user->gid >= 19); // At least J1.5 Author $not_authorised = ! $canAdd; $canPublish = ($user->gid >= 21); } if ( $allowunauthorize ) { $canAdd = true; $canCreateType = true; } } // ... we use some strings from administrator part // load english language file for 'com_flexicontent' component then override with current language file JFactory::getLanguage()->load('com_flexicontent', JPATH_ADMINISTRATOR, 'en-GB', true); JFactory::getLanguage()->load('com_flexicontent', JPATH_ADMINISTRATOR, null, true); // Check for new content if ( ($isnew && !$canAdd) || (!$isnew && !$canEdit)) { $msg = JText::_( 'FLEXI_ALERTNOTAUTH' ); if (FLEXI_J16GE) throw new Exception($msg, 403); else JError::raiseError(403, $msg); } if ( !$canCreateType ) { $msg = isset($types[$type_id]) ? JText::sprintf( 'FLEXI_NO_ACCESS_CREATE_CONTENT_OF_TYPE', JText::_($types[$type_id]->name) ) : ' Content Type '.$type_id.' was not found OR is not published'; if (FLEXI_J16GE) throw new Exception($msg, 403); else JError::raiseError(403, $msg); return; } // Get "BEFORE SAVE" categories for information mail $before_cats = array(); if ( !$isnew ) { $query = 'SELECT DISTINCT c.id, c.title FROM #__categories AS c' . ' JOIN #__flexicontent_cats_item_relations AS rel ON rel.catid = c.id' . ' WHERE rel.itemid = '.(int) $model->get('id'); $db->setQuery( $query ); $before_cats = $db->loadObjectList('id'); $before_maincat = $model->get('catid'); $original_item = $model->getItem($post['id'], $check_view_access=false, $no_cache=true, $force_version=0); } // **************************************** // Try to store the form data into the item // **************************************** if ( ! $model->store($post) ) { // Set error message about saving failed, and also the reason (=model's error message) $msg = JText::_( 'FLEXI_ERROR_STORING_ITEM' ); JError::raiseWarning( 500, $msg .": " . $model->getError() ); // Since an error occured, check if (a) the item is new and (b) was not created if ($isnew && !$model->get('id')) { $msg = ''; $link = 'index.php?option=com_flexicontent&'.$ctrl_task.'add&id=0&typeid='.$type_id.'&'. (FLEXI_J30GE ? JSession::getFormToken() : JUtility::getToken()) .'=1'; $this->setRedirect($link, $msg); } else { $msg = ''; $link = 'index.php?option=com_flexicontent&'.$ctrl_task.'edit&id='.$model->get('id').'&'. (FLEXI_J30GE ? JSession::getFormToken() : JUtility::getToken()) .'=1'; $this->setRedirect($link, $msg); } // Saving has failed check-in and return, (above redirection will be used) $model->checkin(); return; } // ************************************************** // Check in model and get item id in case of new item // ************************************************** $model->checkin(); $post['id'] = $isnew ? (int) $model->get('id') : $post['id']; // Get items marked as newly submitted $newly_submitted = $session->get('newly_submitted', array(), 'flexicontent'); if ($isnew) { // Mark item as newly submitted, to allow to a proper "THANKS" message after final save & close operation (since user may have clicked add instead of add & close) $newly_submitted[$model->get('id')] = 1; $session->set('newly_submitted', $newly_submitted, 'flexicontent'); } $newly_submitted_item = @ $newly_submitted[$model->get('id')]; // *********************************************************************************************************** // Get newly saved -latest- version (store task gets latest) of the item, and also calculate publish privelege // *********************************************************************************************************** $item = $model->getItem($post['id'], $check_view_access=false, $no_cache=true, $force_version=-1); $canPublish = $model->canEditState( $item, $check_cat_perm=true ); // ******************************************************************************************** // Use session to detect multiple item saves to avoid sending notification EMAIL multiple times // ******************************************************************************************** $is_first_save = true; if ($session->has('saved_fcitems', 'flexicontent')) { $saved_fcitems = $session->get('saved_fcitems', array(), 'flexicontent'); $is_first_save = $isnew ? true : !isset($saved_fcitems[$model->get('id')]); } // Add item to saved items of the corresponding session array $saved_fcitems[$model->get('id')] = $timestamp = time(); // Current time as seconds since Unix epoc; $session->set('saved_fcitems', $saved_fcitems, 'flexicontent'); // ******************************************** // Get categories added / removed from the item // ******************************************** $query = 'SELECT DISTINCT c.id, c.title FROM #__categories AS c' . ' JOIN #__flexicontent_cats_item_relations AS rel ON rel.catid = c.id' . ' WHERE rel.itemid = '.(int) $model->get('id'); $db->setQuery( $query ); $after_cats = $db->loadObjectList('id'); if ( !$isnew ) { $cats_added_ids = array_diff(array_keys($after_cats), array_keys($before_cats)); foreach($cats_added_ids as $cats_added_id) { $cats_added_titles[] = $after_cats[$cats_added_id]->title; } $cats_removed_ids = array_diff(array_keys($before_cats), array_keys($after_cats)); foreach($cats_removed_ids as $cats_removed_id) { $cats_removed_titles[] = $before_cats[$cats_removed_id]->title; } $cats_altered = count($cats_added_ids) + count($cats_removed_ids); $after_maincat = $model->get('catid'); } // ******************************************************************************************************************* // We need to get emails to notify, from Global/item's Content Type parameters -AND- from item's categories parameters // ******************************************************************************************************************* $notify_emails = array(); if ( $is_first_save || $cats_altered || $params->get('nf_enable_debug',0) ) { // Get needed flags regarding the saved items $approve_version = 2; $pending_approval_state = -3; $draft_state = -4; $current_version = FLEXIUtilities::getCurrentVersions($item->id, true); // Get current item version $last_version = FLEXIUtilities::getLastVersions($item->id, true); // Get last version (=latest one saved, highest version id), // $post variables vstate & state may have been (a) tampered in the form, and/or (b) altered by save procedure so better not use them $needs_version_reviewal = !$isnew && ($last_version > $current_version) && !$canPublish; $needs_publication_approval = $isnew && ($item->state == $pending_approval_state) && !$canPublish; $draft_from_non_publisher = $item->state==$draft_state && !$canPublish; if ($draft_from_non_publisher) { // Suppress notifications for draft-state items (new or existing ones), for these each author will publication approval manually via a button $nConf = false; } else { // Get notifications configuration and select appropriate emails for current saving case $nConf = $model->getNotificationsConf($params); //echo "<pre>"; print_r($nConf); "</pre>"; } if ($nConf) { $states_notify_new = $params->get('states_notify_new', array(1,0,(FLEXI_J16GE ? 2:-1),-3,-4,-5)); if ( empty($states_notify_new) ) $states_notify_new = array(); else if ( ! is_array($states_notify_new) ) $states_notify_new = !FLEXI_J16GE ? array($states_notify_new) : explode("|", $states_notify_new); $states_notify_existing = $params->get('states_notify_existing', array(1,0,(FLEXI_J16GE ? 2:-1),-3,-4,-5)); if ( empty($states_notify_existing) ) $states_notify_existing = array(); else if ( ! is_array($states_notify_existing) ) $states_notify_existing = !FLEXI_J16GE ? array($states_notify_existing) : explode("|", $states_notify_existing); $n_state_ok = in_array($item->state, $states_notify_new); $e_state_ok = in_array($item->state, $states_notify_existing); if ($needs_publication_approval) $notify_emails = $nConf->emails->notify_new_pending; else if ($isnew && $n_state_ok) $notify_emails = $nConf->emails->notify_new; else if ($isnew) $notify_emails = array(); else if ($needs_version_reviewal) $notify_emails = $nConf->emails->notify_existing_reviewal; else if (!$isnew && $e_state_ok) $notify_emails = $nConf->emails->notify_existing; else if (!$isnew) $notify_emails = array(); if ($needs_publication_approval) $notify_text = $params->get('text_notify_new_pending'); else if ($isnew) $notify_text = $params->get('text_notify_new'); else if ($needs_version_reviewal) $notify_text = $params->get('text_notify_existing_reviewal'); else if (!$isnew) $notify_text = $params->get('text_notify_existing'); //print_r($notify_emails); jexit(); } } // ********************************************************************************************************************* // If there are emails to notify for current saving case, then send the notifications emails, but // ********************************************************************************************************************* if ( !empty($notify_emails) && count($notify_emails) ) { $notify_vars = new stdClass(); $notify_vars->needs_version_reviewal = $needs_version_reviewal; $notify_vars->needs_publication_approval = $needs_publication_approval; $notify_vars->isnew = $isnew; $notify_vars->notify_emails = $notify_emails; $notify_vars->notify_text = $notify_text; $notify_vars->before_cats = $before_cats; $notify_vars->after_cats = $after_cats; $notify_vars->original_item = @ $original_item; $model->sendNotificationEmails($notify_vars, $params, $manual_approval_request=0); } // *************************************************** // CLEAN THE CACHE so that our changes appear realtime // *************************************************** if (FLEXI_J16GE) { $cache = FLEXIUtilities::getCache($group='', 0); $cache->clean('com_flexicontent_items'); $cache->clean('com_flexicontent_filters'); $cache = FLEXIUtilities::getCache($group='', 1); $cache->clean('com_flexicontent_items'); $cache->clean('com_flexicontent_filters'); } else { $itemcache = JFactory::getCache('com_flexicontent_items'); $itemcache->clean(); $filtercache = JFactory::getCache('com_flexicontent_filters'); $filtercache->clean(); } // **************************************************************************************************************************** // Recalculate EDIT PRIVILEGE of new item. Reason for needing to do this is because we can have create permission in a category // and thus being able to set this category as item's main category, but then have no edit/editown permission for this category // **************************************************************************************************************************** if (FLEXI_J16GE) { $asset = 'com_content.article.' . $model->get('id'); $canEdit = $user->authorise('core.edit', $asset) || ($user->authorise('core.edit.own', $asset) && $model->get('created_by') == $user->get('id')); // ALTERNATIVE 1 //$canEdit = $model->getItemAccess()->get('access-edit'); // includes privileges edit and edit-own // ALTERNATIVE 2 //$rights = FlexicontentHelperPerm::checkAllItemAccess($user->get('id'), 'item', $model->get('id')); //$canEdit = in_array('edit', $rights) || (in_array('edit.own', $rights) && $model->get('created_by') == $user->get('id')) ; } else if (FLEXI_ACCESS && $user->gid < 25) { $rights = FAccess::checkAllItemAccess('com_content', 'users', $user->gmid, $model->get('id'), $model->get('catid')); $canEdit = in_array('edit', $rights) || (in_array('editown', $rights) && $model->get('created_by') == $user->get('id')) ; } else { // This is meaningful when executed in frontend, since all backend users (managers and above) can edit items $canEdit = $user->authorize('com_content', 'edit', 'content', 'all') || ($user->authorize('com_content', 'edit', 'content', 'own') && $model->get('created_by') == $user->get('id')); } // ******************************************************************************************************* // Check if user can not edit item further (due to changed main category, without edit/editown permission) // ******************************************************************************************************* if (!$canEdit) { if ($task=='apply') { // APPLY TASK: Temporarily set item to be editable till closing it $rendered_uneditable = $session->get('rendered_uneditable', array(),'flexicontent'); $rendered_uneditable[$model->get('id')] = 1; $session->set('rendered_uneditable', $rendered_uneditable, 'flexicontent'); $canEdit = 1; } else if ( $newly_submitted_item ) { // NEW ITEM: Do not use editable till logoff behaviour // ALSO: Clear editable FLAG set in the case that 'apply' button was used during new item creation if ( !$params->get('items_session_editable', 0) ) { $rendered_uneditable = $session->get('rendered_uneditable', array(),'flexicontent'); if ( isset($rendered_uneditable[$model->get('id')]) ) { unset( $rendered_uneditable[$model->get('id')] ); $session->set('rendered_uneditable', $rendered_uneditable, 'flexicontent'); } } } else { // EXISTING ITEM: (if enabled) Use the editable till logoff behaviour if ( $params->get('items_session_editable', 0) ) { // Set notice for existing item being editable till logoff JError::raiseNotice( 403, JText::_( 'FLEXI_CANNOT_EDIT_AFTER_LOGOFF' ) ); // Allow item to be editable till logoff $rendered_uneditable = $session->get('rendered_uneditable', array(),'flexicontent'); $rendered_uneditable[$model->get('id')] = 1; $session->set('rendered_uneditable', $rendered_uneditable, 'flexicontent'); $canEdit = 1; } } // Set notice about saving an item that cannot be changed further if ( !$canEdit ) { $app->enqueueMessage(JText::_( 'FLEXI_CANNOT_MAKE_FURTHER_CHANGES_TO_CONTENT' ), 'message' ); } } // **************************************************************** // Check for new Content Item is being closed, and clear some flags // **************************************************************** if ($task!='apply' && $newly_submitted_item ) { // Clear item from being marked as newly submitted unset($newly_submitted[$model->get('id')]); $session->set('newly_submitted', $newly_submitted, 'flexicontent'); // The 'apply' task may set 'editable till logoff' FLAG ... // CLEAR IT, since NEW content this is meant to be used temporarily if ( !$params->get('items_session_editable', 0) ) { $rendered_uneditable = $session->get('rendered_uneditable', array(),'flexicontent'); if ( isset($rendered_uneditable[$model->get('id')]) ) { unset( $rendered_uneditable[$model->get('id')] ); $session->set('rendered_uneditable', $rendered_uneditable, 'flexicontent'); } } } } //$this->setRedirect($link, $msg); }