Your IP : 216.73.216.216


Current Path : /proc/self/root/proc/self/root/tmp/
Upload File :
Current File : //proc/self/root/proc/self/root/tmp/php41wdHm

DataModel/Behaviour/Access.php000064400000003365152344664530012257 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Behaviour;

use FOF30\Event\Observer;
use FOF30\Model\DataModel;
use JDatabaseQuery;

defined('_JEXEC') or die;

/**
 * FOF model behavior class to filter access to items based on the viewing access levels.
 *
 * @since    2.1
 */
class Access extends Observer
{
	/**
	 * This event runs after we have built the query used to fetch a record
	 * list in a model. It is used to apply automatic query filters.
	 *
	 * @param   DataModel      &$model The model which calls this event
	 * @param   JDatabaseQuery &$query The query we are manipulating
	 *
	 * @return  void
	 */
	public function onAfterBuildQuery(&$model, &$query)
	{
		// Make sure the field actually exists
		if (!$model->hasField('access'))
		{
			return;
		}

		$model->applyAccessFiltering(null);
	}

	/**
	 * The event runs after DataModel has retrieved a single item from the database. It is used to apply automatic
	 * filters.
	 *
	 * @param   DataModel &$model  The model which was called
	 * @param   Array     &$keys   The keys used to locate the record which was loaded
	 *
	 * @return  void
	 */
	public function onAfterLoad(&$model, &$keys)
	{
		// Make sure we have a DataModel
		if (!($model instanceof DataModel))
		{
			return;
		}

		// Make sure the field actually exists
		if (!$model->hasField('access'))
		{
			return;
		}

		// Get the user
		$user = $model->getContainer()->platform->getUser();
		$recordAccessLevel = $model->getFieldValue('access', null);

		// Filter by authorised access levels
		if (!in_array($recordAccessLevel, $user->getAuthorisedViewLevels()))
		{
			$model->reset(true);
		}
	}
}
DataModel/Behaviour/Assets.php000064400000010575152344664530012321 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Behaviour;

use FOF30\Event\Observer;
use FOF30\Model\DataModel;
use JDatabaseQuery;

defined('_JEXEC') or die;

/**
 * FOF model behavior class to add Joomla! ACL assets support
 *
 * @since    2.1
 */
class Assets extends Observer
{
	public function onAfterSave(DataModel &$model)
	{
		if (!$model->hasField('asset_id') || !$model->isAssetsTracked())
		{
			return true;
		}

		$assetFieldAlias = $model->getFieldAlias('asset_id');
        $currentAssetId  = $model->getFieldValue('asset_id');

        unset($model->$assetFieldAlias);

		// Create the object used for inserting/udpating data to the database
		$fields = $model->getTableFields();

		// Let's remove the asset_id field, since we unset the property above and we would get a PHP notice
		if (isset($fields[ $assetFieldAlias ]))
		{
			unset($fields[ $assetFieldAlias ]);
		}

		// Asset Tracking
		$parentId = $model->getAssetParentId();
		$name     = $model->getAssetName();
		$title    = $model->getAssetTitle();

		$asset = \JTable::getInstance('Asset');
		$asset->loadByName($name);

		// Re-inject the asset id.
		$this->$assetFieldAlias = $asset->id;

		// Check for an error.
		$error = $asset->getError();

		// Since we are using JTable, there is no way to mock it and test for failures :(
		// @codeCoverageIgnoreStart
		if ($error)
		{
			throw new \Exception($error);
		}
		// @codeCoverageIgnoreEnd

		// Specify how a new or moved node asset is inserted into the tree.
		// Since we're unsetting the table field before, this statement is always true...
		if (empty($model->$assetFieldAlias) || $asset->parent_id != $parentId)
		{
			$asset->setLocation($parentId, 'last-child');
		}

		// Prepare the asset to be stored.
		$asset->parent_id = $parentId;
		$asset->name      = $name;
		$asset->title     = $title;

		if ($model->getRules() instanceof \JAccessRules)
		{
			$asset->rules = (string) $model->getRules();
		}

		// Since we are using JTable, there is no way to mock it and test for failures :(
		// @codeCoverageIgnoreStart
		if (!$asset->check() || !$asset->store())
		{
			throw new \Exception($asset->getError());
		}
		// @codeCoverageIgnoreEnd

		// Create an asset_id or heal one that is corrupted.
		if (empty($model->$assetFieldAlias) || (($currentAssetId != $model->$assetFieldAlias) && !empty($model->$assetFieldAlias)))
		{
			// Update the asset_id field in this table.
			$model->$assetFieldAlias = (int) $asset->id;

			$k = $model->getKeyName();

			$db = $model->getDbo();

			$query = $db->getQuery(true)
			            ->update($db->qn($model->getTableName()))
			            ->set($db->qn($assetFieldAlias) . ' = ' . (int) $model->$assetFieldAlias)
			            ->where($db->qn($k) . ' = ' . (int) $model->$k);

			$db->setQuery($query)->execute();
		}

		return true;
	}

	public function onAfterBind(DataModel &$model, &$src)
	{
		if (!$model->isAssetsTracked())
		{
			return true;
		}

		// Bind the rules.
		if (isset($src['rules']) && is_array($src['rules']))
		{
			// We have to manually remove any empty value, since they will be converted to int,
			// and "Inherited" values will become "Denied". Joomla is doing this manually, too.
			$rules = array();

			foreach ($src['rules'] as $action => $ids)
			{
				// Build the rules array.
				$rules[$action] = array();

				foreach ($ids as $id => $p)
				{
					if ($p !== '')
					{
						$rules[$action][$id] = ($p == '1' || $p == 'true') ? true : false;
					}
				}
			}

			$model->setRules($rules);
		}

		return true;
	}

	public function onBeforeDelete(DataModel &$model, $oid)
	{
		if (!$model->isAssetsTracked())
		{
			return true;
		}

		$k = $model->getKeyName();

		// If the table is not loaded, let's try to load it with the id
		if(!$model->$k)
		{
			$model->load($oid);
		}

		// If I have an invalid assetName I have to stop
		$name = $model->getAssetName();

		// Do NOT touch JTable here -- we are loading the core asset table which is a JTable, not a FOF Table
		$asset =\ JTable::getInstance('Asset');

		if ($asset->loadByName($name))
		{
			// Since we are using JTable, there is no way to mock it and test for failures :(
			// @codeCoverageIgnoreStart
			if (!$asset->delete())
			{
				throw new \Exception($asset->getError());
			}
			// @codeCoverageIgnoreEnd
		}

		return true;
	}
}
DataModel/Behaviour/ContentHistory.php000064400000004372152344664530014051 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Behaviour;

use FOF30\Event\Observer;
use FOF30\Model\DataModel;
use JDatabaseQuery;

defined('_JEXEC') or die;

/**
 * FOF model behavior class to add Joomla! content history support
 *
 * @since    2.1
 */
class ContentHistory extends Observer
{
    /** @var  \JHelperContenthistory */
    protected $historyHelper;

	/**
	 * The event which runs after storing (saving) data to the database
	 *
	 * @param   DataModel  &$model  The model which calls this event
	 *
	 * @return  boolean  True to allow saving without an error
	 */
	public function onAfterSave(&$model)
	{
		$aliasParts = explode('.', $model->getContentType());
		$model->checkContentType();

		if (\JComponentHelper::getParams($aliasParts[0])->get('save_history', 0))
		{
            if(!$this->historyHelper)
            {
                $this->historyHelper = new \JHelperContenthistory($model->getContentType());
            }

			$this->historyHelper->store($model);
		}

		return true;
	}

	/**
	 * The event which runs before deleting a record
	 *
	 * @param   DataModel &$model  The model which calls this event
	 * @param   integer   $oid  The PK value of the record to delete
	 *
	 * @return  boolean  True to allow the deletion
	 */
	public function onBeforeDelete(&$model, $oid)
	{
		$aliasParts = explode('.', $model->getContentType());

		if (\JComponentHelper::getParams($aliasParts[0])->get('save_history', 0))
		{
            if(!$this->historyHelper)
            {
                $this->historyHelper = new \JHelperContenthistory($model->getContentType());
            }

			$this->historyHelper->deleteHistory($model);
		}

		return true;
	}

	/**
	 * This event runs after publishing a record in a model
	 *
	 * @param   DataModel  &$model  The model which calls this event
	 *
	 * @return  void
	 */
	public function onAfterPublish(&$model)
	{
		$model->updateUcmContent();
	}

	/**
	 * This event runs after unpublishing a record in a model
	 *
	 * @param   DataModel  &$model  The model which calls this event
	 *
	 * @return  void
	 */
	public function onAfterUnpublish(&$model)
	{
		$model->updateUcmContent();
	}
}
DataModel/Behaviour/Created.php000064400000003717152344664530012426 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Behaviour;

use FOF30\Event\Observer;
use FOF30\Model\DataModel;
use JDatabaseQuery;

defined('_JEXEC') or die;

/**
 * FOF model behavior class to updated the created_by and created_on fields on newly created records.
 *
 * This behaviour is added to DataModel by default. If you want to remove it you need to do
 * $this->behavioursDispatcher->removeBehaviour('Created');
 *
 * @since  3.0
 */
class Created extends Observer
{
	/**
	 * Add the created_on and created_by fields in the fieldsSkipChecks list of the model. We expect them to be empty
	 * so that we can fill them in through this behaviour.
	 *
	 * @param   DataModel  $model
	 */
	public function onBeforeCheck(&$model)
	{
		$model->addSkipCheckField('created_on');
		$model->addSkipCheckField('created_by');
	}

	/**
	 * @param   DataModel  $model
	 * @param   \stdClass  $dataObject
	 */
	public function onBeforeCreate(&$model, &$dataObject)
	{
		// Handle the created_on field
		if ($model->hasField('created_on'))
		{
			$nullDate = $model->getDbo()->getNullDate();
			$created_on = $model->getFieldValue('created_on');

			if (empty($created_on) || ($created_on == $nullDate))
			{
				$model->setFieldValue('created_on', $model->getContainer()->platform->getDate()->toSql(false, $model->getDbo()));

				$createdOnField = $model->getFieldAlias('created_on');
				$dataObject->$createdOnField = $model->getFieldValue('created_on');
			}
		}

		// Handle the created_by field
		if ($model->hasField('created_by'))
		{
			$created_by = $model->getFieldValue('created_by');

			if (empty($created_by))
			{
				$model->setFieldValue('created_by', $model->getContainer()->platform->getUser()->id);

				$createdByField = $model->getFieldAlias('created_by');
				$dataObject->$createdByField = $model->getFieldValue('created_by');
			}
		}
	}
}
DataModel/Behaviour/EmptyNonZero.php000064400000001565152344664530013467 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Behaviour;

use FOF30\Event\Observer;
use FOF30\Model\DataModel;
use JDatabaseQuery;

defined('_JEXEC') or die;

/**
 * FOF model behavior class to let the Filters behaviour know that zero value is a valid filter value
 *
 * @since    2.1
 */
class EmptyNonZero extends Observer
{
	/**
	 * This event runs after we have built the query used to fetch a record
	 * list in a model. It is used to apply automatic query filters.
	 *
	 * @param   DataModel      &$model The model which calls this event
	 * @param   JDatabaseQuery &$query The query we are manipulating
	 *
	 * @return  void
	 */
	public function onAfterBuildQuery(&$model, &$query)
	{
		$model->setBehaviorParam('filterZero', 1);
	}
}
DataModel/Behaviour/Enabled.php000064400000003250152344664530012401 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Behaviour;

use FOF30\Event\Observer;
use FOF30\Model\DataModel;
use JDatabaseQuery;

defined('_JEXEC') or die;

/**
 * FOF model behavior class to filter access to items based on the enabled status
 *
 * @since    2.1
 */
class Enabled extends Observer
{
	/**
	 * This event runs before we have built the query used to fetch a record
	 * list in a model. It is used to apply automatic query filters.
	 *
	 * @param   DataModel      &$model The model which calls this event
	 * @param   JDatabaseQuery &$query The query we are manipulating
	 *
	 * @return  void
	 */
	public function onBeforeBuildQuery(&$model, &$query)
	{
		// Make sure the field actually exists
		if (!$model->hasField('enabled'))
		{
			return;
		}

		$fieldName = $model->getFieldAlias('enabled');
		$db = $model->getDbo();

		$model->whereRaw($db->qn($fieldName) . ' = ' . $db->q(1));
	}

	/**
	 * The event runs after DataModel has retrieved a single item from the database. It is used to apply automatic
	 * filters.
	 *
	 * @param   DataModel &$model  The model which was called
	 * @param   Array     &$keys   The keys used to locate the record which was loaded
	 *
	 * @return  void
	 */
	public function onAfterLoad(&$model, &$keys)
	{
		// Make sure we have a DataModel
		if (!($model instanceof DataModel))
		{
			return;
		}

		// Make sure the field actually exists
		if (!$model->hasField('enabled'))
		{
			return;
		}

		// Filter by enabled status
		if (!$model->getFieldValue('enabled', 0))
		{
			$model->reset(true);
		}
	}
}
DataModel/Behaviour/Filters.php000064400000006723152344664530012467 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Behaviour;

use FOF30\Event\Observer;
use FOF30\Model\DataModel;
use JDatabaseQuery;
use Joomla\Registry\Registry;

defined('_JEXEC') or die;

class Filters extends Observer
{
	/**
	 * This event runs after we have built the query used to fetch a record
	 * list in a model. It is used to apply automatic query filters.
	 *
	 * @param   DataModel  &$model  The model which calls this event
	 * @param   JDatabaseQuery      &$query  The query we are manipulating
	 *
	 * @return  void
	 */
	public function onAfterBuildQuery(&$model, &$query)
	{
		$tableKey = $model->getIdFieldName();
		$db = $model->getDbo();

		$fields     = $model->getTableFields();
		$blacklist  = $model->getBlacklistFilters();
		$filterZero = $model->getBehaviorParam('filterZero', null);
		$tableAlias = $model->getBehaviorParam('tableAlias', null);

		foreach ($fields as $fieldname => $fieldmeta)
		{
			if (in_array($fieldname, $blacklist))
			{
				continue;
			}

			$fieldInfo = (object)array(
				'name'	=> $fieldname,
				'type'	=> $fieldmeta->Type,
				'filterZero' => $filterZero,
				'tableAlias' => $tableAlias,
			);

			$filterName = $fieldInfo->name;
			$filterState = $model->getState($filterName, null);

			// Special primary key handling: if ignore request is set we'll also look for an 'id' state variable if a
			// state variable by the same name as the key doesn't exist. If ignore request is not set in the model we
			// do not filter by 'id' since this interferes with going from an edit page to a browse page (the list is
			// filtered by id without user controls to unset it).
			if ($fieldInfo->name == $tableKey)
			{
				$filterState = $model->getState($filterName, null);

				if (!$model->getIgnoreRequest())
				{
					continue;
				}

				if (empty($filterState))
				{
					$filterState = $model->getState('id', null);
				}
			}

			$field = DataModel\Filter\AbstractFilter::getField($fieldInfo, array('dbo' => $db));

			if (!is_object($field) || !($field instanceof DataModel\Filter\AbstractFilter))
			{
				continue;
			}

			if ((is_array($filterState) && (
						array_key_exists('value', $filterState) ||
						array_key_exists('from', $filterState) ||
						array_key_exists('to', $filterState)
					)) || is_object($filterState))
			{
				$options = class_exists('JRegistry') ? new \JRegistry($filterState) : new Registry($filterState);
			}
			else
			{
				$options = class_exists('JRegistry') ? new \JRegistry() : new Registry();
				$options->set('value', $filterState);
			}

			$methods = $field->getSearchMethods();
			$method = $options->get('method', $field->getDefaultSearchMethod());

			if (!in_array($method, $methods))
			{
				$method = 'exact';
			}

			switch ($method)
			{
				case 'between':
				case 'outside':
				case 'range' :
					$sql = $field->$method($options->get('from', null), $options->get('to', null), $options->get('include', false));
					break;

				case 'interval':
				case 'modulo':
					$sql = $field->$method($options->get('value', null), $options->get('interval'));
					break;

				case 'search':
					$sql = $field->$method($options->get('value', null), $options->get('operator', '='));
					break;

				case 'exact':
				case 'partial':
				default:
					$sql = $field->$method($options->get('value', null));
					break;
			}

			if ($sql)
			{
				$query->where($sql);
			}
		}
	}
}
DataModel/Behaviour/Language.php000064400000011022152344664530012566 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Behaviour;

use FOF30\Event\Observer;
use FOF30\Model\DataModel;
use JDatabaseQuery;
use Joomla\Registry\Registry;

defined('_JEXEC') or die;

/**
 * FOF model behavior class to filter front-end access to items
 * based on the language.
 *
 * @since    2.1
 */
class Language extends Observer
{
    /** @var  \PlgSystemLanguageFilter */
    protected $lang_filter_plugin;

	/**
	 * This event runs before we have built the query used to fetch a record
	 * list in a model. It is used to blacklist the language filter
	 *
	 * @param   DataModel       &$model  The model which calls this event
	 * @param   JDatabaseQuery  &$query  The model which calls this event
	 *
	 * @return  void
	 */
	public function onBeforeBuildQuery(&$model, &$query)
	{
		if ($model->getContainer()->platform->isFrontend())
		{
			$model->blacklistFilters('language');
		}

		// Make sure the field actually exists AND we're not in CLI
		if (!$model->hasField('language') || $model->getContainer()->platform->isCli())
		{
			return;
		}

		/** @var \JApplicationSite $app */
		$app = \JFactory::getApplication();
		$hasLanguageFilter = method_exists($app, 'getLanguageFilter');

		if ($hasLanguageFilter)
		{
			$hasLanguageFilter = $app->getLanguageFilter();
		}

		if (!$hasLanguageFilter)
		{
			return;
		}

        // Ask Joomla for the plugin only if we don't already have it. Useful for tests
        if(!$this->lang_filter_plugin)
        {
            $this->lang_filter_plugin = \JPluginHelper::getPlugin('system', 'languagefilter');
        }

		$lang_filter_params = class_exists('JRegistry') ? new \JRegistry($this->lang_filter_plugin->params) : new Registry($this->lang_filter_plugin->params);

		$languages = array('*');

		if ($lang_filter_params->get('remove_default_prefix'))
		{
			// Get default site language
            $platform    = $model->getContainer()->platform;
			$lg          = $platform->getLanguage();
			$languages[] = $lg->getTag();
		}
		else
		{
            // We have to use JInput since the language fragment is not set in the $_REQUEST, thus we won't have it in our model
            // TODO Double check the previous assumption
			$languages[] = \JFactory::getApplication()->input->getCmd('language', '*');
		}

		// Filter out double languages
		$languages = array_unique($languages);

		// And filter the query output by these languages
		$db = $model->getDbo();
		$languages = array_map(array($db, 'quote'), $languages);
		$fieldName = $model->getFieldAlias('language');

		$model->whereRaw($db->qn($fieldName) . ' IN(' . implode(', ', $languages) . ')');
	}

	/**
	 * The event runs after DataModel has retrieved a single item from the database. It is used to apply automatic
	 * filters.
	 *
	 * @param   DataModel &$model  The model which was called
	 * @param   Array     &$keys   The keys used to locate the record which was loaded
	 *
	 * @return  void
	 */
	public function onAfterLoad(&$model, &$keys)
	{
		// Make sure we have a DataModel
		if (!($model instanceof DataModel))
		{
			return;
		}

		// Make sure the field actually exists AND we're not in CLI
		if (!$model->hasField('language') || $model->getContainer()->platform->isCli())
		{
			return;
		}

		// Make sure it is a multilingual site and get a list of languages
		/** @var \JApplicationSite $app */
		$app = \JFactory::getApplication();
		$hasLanguageFilter = method_exists($app, 'getLanguageFilter');

		if ($hasLanguageFilter)
		{
			$hasLanguageFilter = $app->getLanguageFilter();
		}

		if (!$hasLanguageFilter)
		{
			return;
		}

        // Ask Joomla for the plugin only if we don't already have it. Useful for tests
        if(!$this->lang_filter_plugin)
        {
            $this->lang_filter_plugin = \JPluginHelper::getPlugin('system', 'languagefilter');
        }

		$lang_filter_params = class_exists('JRegistry') ? new \JRegistry($this->lang_filter_plugin->params) : new Registry($this->lang_filter_plugin->params);

		$languages = array('*');

		if ($lang_filter_params->get('remove_default_prefix'))
		{
			// Get default site language
			$lg = $model->getContainer()->platform->getLanguage();
			$languages[] = $lg->getTag();
		}
		else
		{
			$languages[] = \JFactory::getApplication()->input->getCmd('language', '*');
		}

		// Filter out double languages
		$languages = array_unique($languages);

		// Filter by language
		if (!in_array($model->getFieldValue('language'), $languages))
		{
			$model->reset();
		}
	}
}
DataModel/Behaviour/Modified.php000064400000003560152344664530012573 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Behaviour;

use FOF30\Event\Observer;
use FOF30\Model\DataModel;
use JDatabaseQuery;

defined('_JEXEC') or die;

/**
 * FOF model behavior class to updated the modified_by and modified_on fields on newly created records.
 *
 * This behaviour is added to DataModel by default. If you want to remove it you need to do
 * $this->behavioursDispatcher->removeBehaviour('Modified');
 *
 * @since  3.0
 */
class Modified extends Observer
{
	/**
	 * Add the modified_on and modified_by fields in the fieldsSkipChecks list of the model. We expect them to be empty
	 * so that we can fill them in through this behaviour.
	 *
	 * @param   DataModel  $model
	 */
	public function onBeforeCheck(&$model)
	{
		$model->addSkipCheckField('modified_on');
		$model->addSkipCheckField('modified_by');
	}

	/**
	 * @param   DataModel  $model
	 * @param   \stdClass  $dataObject
	 */
	public function onBeforeUpdate(&$model, &$dataObject)
	{
		// Make sure we're not modifying a locked record
		$userId = $model->getContainer()->platform->getUser()->id;
		$isLocked = $model->isLocked($userId);

		if ($isLocked)
		{
			return;
		}

		// Handle the modified_on field
		if ($model->hasField('modified_on'))
		{
			$model->setFieldValue('modified_on', $model->getContainer()->platform->getDate()->toSql(false, $model->getDbo()));

			$modifiedOnField = $model->getFieldAlias('modified_on');
			$dataObject->$modifiedOnField = $model->getFieldValue('modified_on');
		}

		// Handle the modified_by field
		if ($model->hasField('modified_by'))
		{
			$model->setFieldValue('modified_by', $userId);

			$modifiedByField = $model->getFieldAlias('modified_by');
			$dataObject->$modifiedByField = $model->getFieldValue('modified_by');
		}
	}
}
DataModel/Behaviour/Own.php000064400000003727152344664530011623 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Behaviour;

use FOF30\Event\Observer;
use FOF30\Model\DataModel;
use JDatabaseQuery;

defined('_JEXEC') or die;

/**
 * FOF model behavior class to filter access to items owned by the currently logged in user only
 *
 * @since    2.1
 */
class Own extends Observer
{
	/**
	 * This event runs after we have built the query used to fetch a record
	 * list in a model. It is used to apply automatic query filters.
	 *
	 * @param   DataModel      &$model The model which calls this event
	 * @param   JDatabaseQuery &$query The query we are manipulating
	 *
	 * @return  void
	 */
	public function onAfterBuildQuery(&$model, &$query)
	{
		// Make sure the field actually exists
		if (!$model->hasField('created_by'))
		{
			return;
		}

		// Get the current user's id
		$user_id = $model->getContainer()->platform->getUser()->id;

		// And filter the query output by the user id
		$db    = $model->getContainer()->platform->getDbo();

		$query->where($db->qn($model->getFieldAlias('created_by')) . ' = ' . $db->q($user_id));
	}

	/**
	 * The event runs after DataModel has retrieved a single item from the database. It is used to apply automatic
	 * filters.
	 *
	 * @param   DataModel &$model  The model which was called
	 * @param   Array     &$keys   The keys used to locate the record which was loaded
	 *
	 * @return  void
	 */
	public function onAfterLoad(&$model, &$keys)
	{
		// Make sure we have a DataModel
		if (!($model instanceof DataModel))
		{
			return;
		}

		// Make sure the field actually exists
		if (!$model->hasField('created_by'))
		{
			return;
		}

		// Get the user
		$user_id = $model->getContainer()->platform->getUser()->id;
		$recordUser = $model->getFieldValue('created_by', null);

		// Filter by authorised access levels
		if ($recordUser != $user_id)
		{
			$model->reset(true);
		}
	}
}
DataModel/Behaviour/PageParametersToState.php000064400000002770152344664530015261 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Behaviour;

use FOF30\Event\Observer;
use FOF30\Model\DataModel;
use Joomla\Registry\Registry;

defined('_JEXEC') or die;

/**
 * FOF model behavior class to populate the state with the front-end page parameters
 *
 * @since    2.1
 */
class PageParametersToState extends Observer
{
	public function onAfterConstruct(DataModel &$model)
	{
		// This only applies to the front-end
		if (!$model->getContainer()->platform->isFrontend())
		{
			return;
		}

		// Get the page parameters
		/** @var \JApplicationSite $app */
		$app    = \JFactory::getApplication();
		/** @var \JRegistry|Registry $params */
		$params = $app->getParams();

		// Extract the page parameter keys
		$asArray = $params->toArray();

		if (empty($asArray))
		{
			// There are no keys; no point in going on.
			return;
		}

		$keys = array_keys($asArray);
		unset($asArray);

		// Loop all page parameter keys
		foreach ($keys as $key)
		{
			// This is the current model state
			$currentState = $model->getState($key);
			// This is the explicitly requested state in the input
			$explicitInput = $model->input->get($key, null, 'raw');

			// If the current state is empty and there's no explicit input we'll use the page parameters instead
			if (is_null($currentState) && is_null($explicitInput))
			{
				$model->setState($key, $params->get($key));
			}
		}
	}
}
DataModel/Behaviour/RelationFilters.php000064400000004376152344664530014167 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Behaviour;

use FOF30\Event\Observer;
use FOF30\Model\DataModel;
use Joomla\Registry\Registry;
use JRegistry;

defined('_JEXEC') or die;

class RelationFilters extends Observer
{
	/**
	 * This event runs after we have built the query used to fetch a record list in a model. It is used to apply
	 * automatic query filters based on model relations.
	 *
	 * @param   DataModel  &$model  The model which calls this event
	 * @param   \JDatabaseQuery      &$query  The query we are manipulating
	 *
	 * @return  void
	 */
	public function onAfterBuildQuery(&$model, &$query)
	{
		$relationFilters = $model->getRelationFilters();

		foreach ($relationFilters as $filterState)
		{
			$relationName = $filterState['relation'];

			$tableAlias = $model->getBehaviorParam('tableAlias', null);
			$subQuery = $model->getRelations()->getCountSubquery($relationName, $tableAlias);

			// Callback method needs different handling
			if (isset($filterState['method']) && ($filterState['method'] == 'callback'))
			{
				call_user_func_array($filterState['value'], array(&$subQuery));
				$filterState['method'] = 'search';
				$filterState['operator'] = '>=';
				$filterState['value'] = '1';
			}

			$options = class_exists('JRegistry') ? new JRegistry($filterState) : new Registry($filterState);

			$filter = new DataModel\Filter\Relation($model->getDbo(), $relationName, $subQuery);
			$methods = $filter->getSearchMethods();
			$method = $options->get('method', $filter->getDefaultSearchMethod());

			if (!in_array($method, $methods))
			{
				$method = 'exact';
			}

			switch ($method)
			{
				case 'between':
				case 'outside':
					$sql = $filter->$method($options->get('from', null), $options->get('to'));
					break;

				case 'interval':
					$sql = $filter->$method($options->get('value', null), $options->get('interval'));
					break;

				case 'search':
					$sql = $filter->$method($options->get('value', null), $options->get('operator', '='));
					break;

				default:
					$sql = $filter->$method($options->get('value', null));
					break;
			}

			if ($sql)
			{
				$query->where($sql);
			}
		}
	}
} 
DataModel/Behaviour/Tags.php000064400000007655152344664530011762 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Behaviour;

use FOF30\Event\Observer;
use FOF30\Model\DataModel;
use FOF30\Event\Observable;

defined('_JEXEC') or die;

/**
 * FOF model behavior class to add Joomla! Tags support
 *
 * @since    2.1
 */
class Tags extends Observer
{
    /** @var \JHelperTags  */
    protected $tagsHelper;

	public function __construct(Observable &$subject)
	{
		parent::__construct($subject);

		$this->tagsHelper = new \JHelperTags();
	}

	/**
	 * This event runs after unpublishing a record in a model
	 *
	 * @param   DataModel  &$model        The model which calls this event
	 * @param   \stdClass  &$dataObject   The data to bind to the form
	 *
	 * @return  void
	 */
	public function onBeforeCreate(&$model, &$dataObject)
	{
		$tagField = $model->getBehaviorParam('tagFieldName', 'tags');

		unset($dataObject->$tagField);
	}

	/**
	 * This event runs after unpublishing a record in a model
	 *
	 * @param   DataModel  &$model        The model which calls this event
	 * @param   \stdClass  &$dataObject   The data to bind to the form
	 *
	 * @return  void
	 */
	public function onBeforeUpdate(&$model, &$dataObject)
	{
		$tagField = $model->getBehaviorParam('tagFieldName', 'tags');

		unset($dataObject->$tagField);
	}

	/**
	 * The event which runs after binding data to the table
	 *
	 * @param   DataModel    &$model  The model which calls this event
	 *
	 * @return  void
	 *
	 * @throws  \Exception  Error message if failed to store tags
	 */
	public function onAfterSave(&$model)
	{
		$tagField = $model->getBehaviorParam('tagFieldName', 'tags');

		// Avoid to update on other method (e.g. publish, ...)
		if (!in_array($model->getContainer()->input->getCmd('task'), array('apply', 'save', 'savenew')))
		{
			return;
		}

		$oldTags = $this->tagsHelper->getTagIds($model->getId(), $model->getContentType());
		$newTags = $model->$tagField ? implode(',', $model->$tagField) : null;

		// If no changes, we stop here
		if ($oldTags == $newTags)
		{
			return;
		}

		// Check if the content type exists, and create it if it does not
		$model->checkContentType();

		$this->tagsHelper->typeAlias = $model->getContentType();

		if (!$this->tagsHelper->postStoreProcess($model, $model->$tagField))
		{
			throw new \Exception('Error storing tags');
		}
	}

	/**
	 * The event which runs after deleting a record
	 *
	 * @param   DataModel &$model The model which calls this event
	 * @param   integer   $oid    The PK value of the record which was deleted
	 *
	 * @return  void
	 *
	 * @throws  \Exception  Error message if failed to detele tags
	 */
	public function onAfterDelete(&$model, $oid)
	{
		$this->tagsHelper->typeAlias = $model->getContentType();

		if (!$this->tagsHelper->deleteTagData($model, $oid))
		{
			throw new \Exception('Error deleting Tags');
		}
	}

	/**
	 * This event runs after unpublishing a record in a model
	 *
	 * @param   DataModel  &$model  The model which calls this event
	 * @param   mixed      $data    An associative array or object to bind to the DataModel instance.
	 *
	 * @return  void
	 */
	public function onAfterBind(&$model, &$data)
	{
		$tagField = $model->getBehaviorParam('tagFieldName', 'tags');

		if ($model->$tagField)
		{
			return;
		}

		$type = $model->getContentType();

		$model->addKnownField($tagField);
		$model->$tagField = $this->tagsHelper->getTagIds($model->getId(), $type);
	}

	/**
	 * This event runs after publishing a record in a model
	 *
	 * @param   DataModel  &$model  The model which calls this event
	 *
	 * @return  void
	 */
	public function onAfterPublish(&$model)
	{
		$model->updateUcmContent();
	}

	/**
	 * This event runs after unpublishing a record in a model
	 *
	 * @param   DataModel  &$model  The model which calls this event
	 *
	 * @return  void
	 */
	public function onAfterUnpublish(&$model)
	{
		$model->updateUcmContent();
	}
}
DataModel/Exception/BaseException.php000064400000000426152344664530013614 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Exception;

defined('_JEXEC') or die;

class BaseException extends \RuntimeException
{

}
DataModel/Exception/CannotLockNotLoadedRecord.php000064400000001050152344664530016041 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Exception;

use Exception;

defined('_JEXEC') or die;

class CannotLockNotLoadedRecord extends BaseException
{
	public function __construct( $message = '', $code = 500, Exception $previous = null )
	{
		if (empty($message))
		{
			$message = \JText::_('LIB_FOF_MODEL_ERR_CANNOTLOCKNOTLOADEDRECORD');
		}

		parent::__construct( $message, $code, $previous );
	}

}
DataModel/Exception/InvalidSearchMethod.php000064400000000430152344664530014733 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Exception;

defined('_JEXEC') or die;

class InvalidSearchMethod extends BaseException
{

}
DataModel/Exception/NoAssetKey.php000064400000001026152344664530013105 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Exception;

use Exception;

defined('_JEXEC') or die;

class NoAssetKey extends \UnexpectedValueException
{
	public function __construct( $message = '', $code = 500, Exception $previous = null )
	{
		if (empty($message))
		{
			$message = \JText::_('LIB_FOF_MODEL_ERR_NOASSETKEY');
		}

		parent::__construct( $message, $code, $previous );
	}

}
DataModel/Exception/NoContentType.php000064400000001013152344664530013625 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Exception;

use Exception;

defined('_JEXEC') or die;

class NoContentType extends \UnexpectedValueException
{
	public function __construct( $className, $code = 500, Exception $previous = null )
	{
		$message = \JText::sprintf('LIB_FOF_MODEL_ERR_NOCONTENTTYPE', $className);

		parent::__construct( $message, $code, $previous );
	}

}
DataModel/Exception/NoItemsFound.php000064400000000775152344664530013444 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Exception;

use Exception;

defined('_JEXEC') or die;

class NoItemsFound extends BaseException
{
	public function __construct( $className, $code = 404, Exception $previous = null )
	{
		$message = \JText::sprintf('LIB_FOF_MODEL_ERR_NOITEMSFOUND', $className);

		parent::__construct( $message, $code, $previous );
	}

}
DataModel/Exception/NoTableColumns.php000064400000000423152344664530013745 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Exception;

defined('_JEXEC') or die;

class NoTableColumns extends BaseException
{

}
DataModel/Exception/RecordNotLoaded.php000064400000001021152344664530014063 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Exception;

use Exception;

defined('_JEXEC') or die;

class RecordNotLoaded extends BaseException
{
	public function __construct( $message = "", $code = 404, Exception $previous = null )
	{
		if (empty($message))
		{
			$message = \JText::_('LIB_FOF_MODEL_ERR_COULDNOTLOAD');
		}

		parent::__construct( $message, $code, $previous );
	}

}
DataModel/Exception/SpecialColumnMissing.php000064400000000431152344664530015147 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Exception;

defined('_JEXEC') or die;

class SpecialColumnMissing extends BaseException
{

}
DataModel/Exception/TreeIncompatibleTable.php000064400000001034152344664530015255 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Exception;

use Exception;

defined('_JEXEC') or die;

class TreeIncompatibleTable extends \UnexpectedValueException
{
	public function __construct( $tableName, $code = 500, Exception $previous = null )
	{
		$message = \JText::sprintf('LIB_FOF_MODEL_ERR_TREE_INCOMPATIBLETABLE', $tableName);

		parent::__construct( $message, $code, $previous );
	}

}
DataModel/Exception/TreeInvalidLftRgt.php000064400000000705152344664530014414 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Exception;

use Exception;

defined('_JEXEC') or die;

abstract class TreeInvalidLftRgt extends \RuntimeException
{
	public function __construct( $message = '', $code = 500, Exception $previous = null )
	{
		parent::__construct( $message, $code, $previous );
	}

}
DataModel/Exception/TreeInvalidLftRgtCurrent.php000064400000001054152344664530015755 0ustar00<?php
/**
 * @package     FOF
 * @copyright   Copyright (c)2010-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license     GNU GPL version 2 or later
 */

namespace FOF30\Model\DataModel\Exception;

use Exception;

defined('_JEXEC') or die;

class TreeInvalidLftRgtCurrent extends TreeInvalidLftRgt
{
	public function __construct( $message = '', $code = 500, Exception $previous = null )
	{
		if (empty($message))
		{
			$message = \JText::_('LIB_FOF_MODEL_ERR_TREE_INVALIDLFTRGT_CURRENT');
		}

		parent::__construct( $message, $code, $previous );
	}

}
DataModel/Exception/TreeInvalidLftRgtOther.php000064400000001050152344664530015410 0ustar00