示例#1
0
 /**
  * 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');
 }
示例#2
0
 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;
 }
示例#4
0
    /**
     * 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 . "' : &nbsp; 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) . '&amp;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);
 }
示例#7
0
 /**
  * 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');
 }
示例#8
0
	/**
	 * 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);
	}
示例#9
0
        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);
	}