241 lines
6.5 KiB
PHP
241 lines
6.5 KiB
PHP
<?php
|
|
/**
|
|
* @package FrameworkOnFramework
|
|
* @subpackage table
|
|
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
|
*/
|
|
// Protect from unauthorized access
|
|
defined('F0F_INCLUDED') or die;
|
|
|
|
/**
|
|
* FrameworkOnFramework table behavior class for assets
|
|
*
|
|
* @package FrameworkOnFramework
|
|
* @since 2.1
|
|
*/
|
|
class F0FTableBehaviorAssets extends F0FTableBehavior
|
|
{
|
|
/**
|
|
* The event which runs after storing (saving) data to the database
|
|
*
|
|
* @param F0FTable &$table The table which calls this event
|
|
*
|
|
* @return boolean True to allow saving
|
|
*/
|
|
public function onAfterStore(&$table)
|
|
{
|
|
$result = true;
|
|
|
|
$asset_id_field = $table->getColumnAlias('asset_id');
|
|
|
|
if (in_array($asset_id_field, $table->getKnownFields()))
|
|
{
|
|
if (!empty($table->$asset_id_field))
|
|
{
|
|
$currentAssetId = $table->$asset_id_field;
|
|
}
|
|
|
|
// The asset id field is managed privately by this class.
|
|
if ($table->isAssetsTracked())
|
|
{
|
|
unset($table->$asset_id_field);
|
|
}
|
|
}
|
|
|
|
// Create the object used for inserting/udpating data to the database
|
|
$fields = $table->getTableFields();
|
|
|
|
// Let's remove the asset_id field, since we unset the property above and we would get a PHP notice
|
|
if (isset($fields[$asset_id_field]))
|
|
{
|
|
unset($fields[$asset_id_field]);
|
|
}
|
|
|
|
// Asset Tracking
|
|
if (in_array($asset_id_field, $table->getKnownFields()) && $table->isAssetsTracked())
|
|
{
|
|
$parentId = $table->getAssetParentId();
|
|
|
|
try{
|
|
$name = $table->getAssetName();
|
|
}
|
|
catch(Exception $e)
|
|
{
|
|
$table->setError($e->getMessage());
|
|
return false;
|
|
}
|
|
|
|
$title = $table->getAssetTitle();
|
|
|
|
$asset = JTable::getInstance('Asset');
|
|
$asset->loadByName($name);
|
|
|
|
// Re-inject the asset id.
|
|
$this->$asset_id_field = $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)
|
|
{
|
|
$table->setError($error);
|
|
|
|
return false;
|
|
}
|
|
// @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($table->$asset_id_field) || $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 ($table->getRules() instanceof JAccessRules)
|
|
{
|
|
$asset->rules = (string) $table->getRules();
|
|
}
|
|
|
|
// Since we are using JTable, there is no way to mock it and test for failures :(
|
|
// @codeCoverageIgnoreStart
|
|
if (!$asset->check() || !$asset->store())
|
|
{
|
|
$table->setError($asset->getError());
|
|
|
|
return false;
|
|
}
|
|
// @codeCoverageIgnoreEnd
|
|
|
|
// Create an asset_id or heal one that is corrupted.
|
|
if (empty($table->$asset_id_field) || (($currentAssetId != $table->$asset_id_field) && !empty($table->$asset_id_field)))
|
|
{
|
|
// Update the asset_id field in this table.
|
|
$table->$asset_id_field = (int) $asset->id;
|
|
|
|
$k = $table->getKeyName();
|
|
|
|
$db = $table->getDbo();
|
|
|
|
$query = $db->getQuery(true)
|
|
->update($db->qn($table->getTableName()))
|
|
->set($db->qn($asset_id_field).' = ' . (int) $table->$asset_id_field)
|
|
->where($db->qn($k) . ' = ' . (int) $table->$k);
|
|
|
|
$db->setQuery($query)->execute();
|
|
}
|
|
|
|
$result = true;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* The event which runs after binding data to the table
|
|
*
|
|
* @param F0FTable &$table The table which calls this event
|
|
* @param object|array &$src The data to bind
|
|
*
|
|
* @return boolean True on success
|
|
*/
|
|
public function onAfterBind(&$table, &$src)
|
|
{
|
|
// Set rules for assets enabled tables
|
|
if ($table->isAssetsTracked())
|
|
{
|
|
// 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.
|
|
// @todo Should we move this logic inside the setRules method?
|
|
$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;
|
|
}
|
|
}
|
|
}
|
|
|
|
$table->setRules($rules);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* The event which runs before deleting a record
|
|
*
|
|
* @param F0FTable &$table The table 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(&$table, $oid)
|
|
{
|
|
// If tracking assets, remove the asset first.
|
|
if ($table->isAssetsTracked())
|
|
{
|
|
$k = $table->getKeyName();
|
|
|
|
// If the table is not loaded, let's try to load it with the id
|
|
if(!$table->$k)
|
|
{
|
|
$table->load($oid);
|
|
}
|
|
|
|
// If I have an invalid assetName I have to stop
|
|
try
|
|
{
|
|
$name = $table->getAssetName();
|
|
}
|
|
catch(Exception $e)
|
|
{
|
|
$table->setError($e->getMessage());
|
|
return false;
|
|
}
|
|
|
|
// Do NOT touch JTable here -- we are loading the core asset table which is a JTable, not a F0FTable
|
|
$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())
|
|
{
|
|
$table->setError($asset->getError());
|
|
|
|
return false;
|
|
}
|
|
// @codeCoverageIgnoreEnd
|
|
}
|
|
else
|
|
{
|
|
// I'll simply return true even if I couldn't load the asset. In this way I can still
|
|
// delete a broken record
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|