473 lines
12 KiB
PHP
473 lines
12 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @package Advanced Custom Fields
|
|
* @version 2.8.8 Pro
|
|
*
|
|
* @author Tassos Marinos <info@tassos.gr>
|
|
* @link http://www.tassos.gr
|
|
* @copyright Copyright © 2019 Tassos Marinos All Rights Reserved
|
|
* @license GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> or later
|
|
*/
|
|
|
|
defined('_JEXEC') or die('Restricted access');
|
|
|
|
// Initialize ACF Namespace
|
|
require_once __DIR__ . '/autoload.php';
|
|
|
|
use NRFramework\HTML;
|
|
use Joomla\CMS\Factory;
|
|
use Joomla\CMS\Form\Form;
|
|
use Joomla\CMS\Plugin\CMSPlugin;
|
|
use Joomla\CMS\Uri\Uri;
|
|
use Joomla\CMS\Session\Session;
|
|
use Joomla\CMS\Language\Text;
|
|
use Joomla\Registry\Registry;
|
|
use Joomla\CMS\HTML\HTMLHelper;
|
|
use NRFramework\Helpers\Widgets\GalleryManager as GalleryManagerHelper;
|
|
|
|
/**
|
|
* Advanced Custom Fields System Plugin
|
|
*/
|
|
class PlgSystemACF extends CMSPlugin
|
|
{
|
|
/**
|
|
* Auto load plugin's language file
|
|
*
|
|
* @var boolean
|
|
*/
|
|
protected $autoloadLanguage = true;
|
|
|
|
/**
|
|
* Application Object
|
|
*
|
|
* @var object
|
|
*/
|
|
protected $app;
|
|
|
|
/**
|
|
* The loaded indicator of helper
|
|
*
|
|
* @var boolean
|
|
*/
|
|
private $init;
|
|
|
|
/**
|
|
* The field preview data.
|
|
*
|
|
* This is an array that holds
|
|
* both the HTML of the field as well
|
|
* as the assets that it requires.
|
|
*
|
|
* @var array
|
|
*/
|
|
private $field_preview_data = [];
|
|
|
|
public function onAfterInitialise()
|
|
{
|
|
// YooTheme Pro Integration
|
|
\ACF\Helpers\Yoo::initFieldParser();
|
|
}
|
|
|
|
|
|
/**
|
|
* After a tag has been deleted, then delete it from
|
|
* all ACF - Gallery instances.
|
|
*
|
|
* @param string $context
|
|
* @param object $item
|
|
*
|
|
* @return void
|
|
*/
|
|
public function onContentAfterDelete($context, $item)
|
|
{
|
|
// Delete all Joomla article assets
|
|
if ($context === 'com_content.article')
|
|
{
|
|
\ACF\Helpers\Fields\Gallery::deleteFilesFromItem($item->id);
|
|
\ACF\Helpers\Fields\Upload::deleteFilesFromItem($item->id);
|
|
}
|
|
|
|
// Delete all tag assets
|
|
if ($context === 'com_tags.tag')
|
|
{
|
|
GalleryManagerHelper::deleteTagFromFieldsValues($item->id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* onCustomFieldsBeforePrepareField Event
|
|
*/
|
|
public function onCustomFieldsBeforePrepareField($context, $item, &$field)
|
|
{
|
|
// Validate supported component/views
|
|
if (!in_array($context, [
|
|
'com_content.article',
|
|
'com_dpcalendar.event'
|
|
]))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Get Helper
|
|
if (!$this->getHelper())
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Only if assignments option is enabled in the plugin settings
|
|
if (!$this->params->get('assignments', true))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (ACFHelper::checkConditions($field) === false)
|
|
{
|
|
// According to the components/com_fields/layouts/fields/render.php file, if the field's value is empty it won't show up in the front-end.
|
|
$field->value = '';
|
|
|
|
// Unset rawvalue too, as it may be used in template overrides.
|
|
$field->rawvalue = '';
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Append publishing assignments XML to the
|
|
*
|
|
* @param Form $form The form to be altered.
|
|
* @param mixed $data The associated data for the form.
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public function onContentPrepareForm(Form $form, $data)
|
|
{
|
|
|
|
// Run Display Conditions checks for the User Profile page.
|
|
// NOTE: The System Fields plugin must be placed before this plugin in order for the $form to include the custom fields information.
|
|
if ($this->params->get('assignments', true) && $form->getName() == 'com_users.profile' && $this->app->isClient('site') && $form instanceof Form)
|
|
{
|
|
JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR . '/components/com_fields/helpers/fields.php');
|
|
|
|
if ($fields = FieldsHelper::getFields('com_users.user', Factory::getUser(), true))
|
|
{
|
|
foreach ($fields as $field)
|
|
{
|
|
if (ACFHelper::checkConditions($field) === false)
|
|
{
|
|
$form->removeField($field->name, 'com_fields');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Run only on backend
|
|
if (!$this->app->isClient('administrator') || !$form instanceof Form)
|
|
{
|
|
return;
|
|
}
|
|
|
|
$context = $form->getName();
|
|
|
|
|
|
$this->loadPreviewer($context);
|
|
|
|
|
|
if (!in_array($context, [
|
|
'com_fields.field.com_users.user',
|
|
'com_fields.field.com_content.article',
|
|
'com_fields.field.com_contact.contact',
|
|
'com_fields.field.com_dpcalendar.event'
|
|
]))
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
// Load Publishing Rules tab if assignments option is enabled in the plugin settings
|
|
if ($this->params->get('assignments', true))
|
|
{
|
|
$form->loadFile(__DIR__ . '/form/conditions.xml', false);
|
|
|
|
if ($context == 'com_fields.field.com_users.user')
|
|
{
|
|
// If plg_system_fields is not positioned before plg_system_acf, display a warning.
|
|
$db = Factory::getDbo();
|
|
$query = $db->getQuery(true)
|
|
->select('name, ordering')
|
|
->from($db->quoteName('#__extensions'))
|
|
->where($db->quoteName('name') . ' = ' . $db->q('plg_system_acf'))
|
|
->orWhere($db->quoteName('name') . ' = ' . $db->q('plg_system_fields'))
|
|
->order($db->quoteName('ordering'));
|
|
|
|
$db->setQuery($query);
|
|
|
|
$plugins = $db->loadObjectList();
|
|
|
|
if (count($plugins) == 2 && $plugins[0]->name !== 'plg_system_fields')
|
|
{
|
|
$form->setField(new SimpleXMLElement('
|
|
<fieldset name="conditions">
|
|
<field name="wrongPluginOrder" type="note"
|
|
class="alert alert-warning"
|
|
description="ACF_USER_DISPLAY_CONDITIONS_WRONG_PLUGIN_ORDER"
|
|
/>
|
|
</fieldset>
|
|
'));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Load "ACF Options" tab if the option is enabled in the plugin settings
|
|
if ($this->params->get('acf_options', true))
|
|
{
|
|
$form->loadFile(__DIR__ . '/form/options.xml', false);
|
|
}
|
|
|
|
|
|
// Always load our stylesheet even if it's a non-ACF field. The Publishing Rules tab shows up on all fields.
|
|
HTMLHelper::stylesheet('plg_system_acf/acf-backend.css', ['relative' => true, 'version' => 'auto']);
|
|
|
|
if (defined('nrJ4'))
|
|
{
|
|
HTMLHelper::stylesheet('plg_system_acf/joomla4.css', ['relative' => true, 'version' => 'auto']);
|
|
HTMLHelper::stylesheet('plg_system_nrframework/joomla4.css', ['relative' => true, 'version' => 'auto']);
|
|
HTML::fixFieldTooltips();
|
|
} else
|
|
{
|
|
HTMLHelper::stylesheet('plg_system_acf/joomla3.css', ['relative' => true, 'version' => 'auto']);
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* Load previewer assets.
|
|
*
|
|
* @param string $context
|
|
*
|
|
* @return void
|
|
*/
|
|
private function loadPreviewer($context)
|
|
{
|
|
$allowed_context = [
|
|
'com_fields.field.com_content.article',
|
|
'com_fields.field.com_content.categories',
|
|
'com_fields.field.com_contact.contact',
|
|
'com_fields.field.com_contact.mail',
|
|
'com_fields.field.com_contact.categories'
|
|
];
|
|
|
|
if (!in_array($context, $allowed_context))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Data passed as JS object
|
|
$doc = Factory::getDocument();
|
|
$options = $doc->getScriptOptions('acf_js_object');
|
|
$options = is_array($options) ? $options : [];
|
|
$options = [
|
|
'root_url' => Uri::base()
|
|
];
|
|
$doc->addScriptOptions('acf_js_object', $options);
|
|
|
|
// Framework helper to load assets
|
|
HTMLHelper::script('plg_system_nrframework/helper.js', ['relative' => true, 'version' => 'auto']);
|
|
|
|
// Load Field Previewer
|
|
HTMLHelper::script('plg_system_acf/field_previewer.js', ['relative' => true, 'version' => 'auto']);
|
|
}
|
|
|
|
|
|
/**
|
|
* Listens to AJAX requests on ?option=com_ajax&format=raw&plugin=acf
|
|
*
|
|
* @return void
|
|
*/
|
|
public function onAjaxAcf()
|
|
{
|
|
Session::checkToken('request') or jexit(Text::_('JINVALID_TOKEN'));
|
|
|
|
// Only in backend
|
|
if (!$this->app->isClient('administrator'))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Check if we have a valid task
|
|
$task = $this->app->input->get('task', null);
|
|
|
|
// Check if we have a valid method task
|
|
$taskMethod = 'ajaxTask' . $task;
|
|
|
|
if (!method_exists($this, $taskMethod))
|
|
{
|
|
die('Task not found');
|
|
}
|
|
|
|
$this->$taskMethod();
|
|
}
|
|
|
|
/**
|
|
* Fields Previewer.
|
|
*
|
|
* @return string
|
|
*/
|
|
private function ajaxTaskFieldsPreviewer()
|
|
{
|
|
$field = $this->app->input->get('field', null);
|
|
if (!$field)
|
|
{
|
|
echo json_encode([
|
|
'error' => true,
|
|
'message' => 'Missing field name.'
|
|
]);
|
|
die();
|
|
}
|
|
|
|
if (!$data = json_decode(file_get_contents('php://input')))
|
|
{
|
|
echo json_encode([
|
|
'error' => true,
|
|
'message' => 'Missing field data to generate preview.'
|
|
]);
|
|
die();
|
|
}
|
|
|
|
// Prepare data
|
|
$registry = new Registry();
|
|
foreach ($data as $key => $value)
|
|
{
|
|
$key = str_replace(['jform[', ']', '['], ['', '', '.'], $key);
|
|
$registry->set($key, $value);
|
|
}
|
|
$data = $registry->toArray();
|
|
|
|
// We require the type of the field to save the fields data to the JSON file and be able to generate the preview
|
|
if (!isset($data['type']))
|
|
{
|
|
echo json_encode([
|
|
'error' => true,
|
|
'message' => 'Missing field type to generate preview.'
|
|
]);
|
|
die();
|
|
}
|
|
|
|
// ACF Field Previewer Class
|
|
$class = '\ACF\Previewer\\' . $field;
|
|
|
|
// Ensure class exists
|
|
if (!class_exists($class))
|
|
{
|
|
echo json_encode([
|
|
'error' => true,
|
|
'message' => 'Cannot preview field: ' . $field
|
|
]);
|
|
die();
|
|
}
|
|
|
|
// Get class
|
|
$class = new $class($data);
|
|
|
|
// Setup previewer
|
|
$class->setup();
|
|
|
|
echo json_encode([
|
|
'error' => false
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Fields Previewer HTML.
|
|
*
|
|
* @return string
|
|
*/
|
|
private function ajaxTaskFieldsPreviewerHTML()
|
|
{
|
|
$field = $this->app->input->get('field', null);
|
|
if (!$field)
|
|
{
|
|
echo json_encode([
|
|
'error' => true,
|
|
'message' => 'Missing field name.'
|
|
]);
|
|
die();
|
|
}
|
|
|
|
if (!$html = \ACF\Helpers\Previewer::getFieldPreviewData($field))
|
|
{
|
|
return;
|
|
}
|
|
|
|
echo $html;
|
|
}
|
|
|
|
/**
|
|
* Loads the helper classes of plugin
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function getHelper()
|
|
{
|
|
// Return if is helper is already loaded
|
|
if ($this->init)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// Return if we are not in frontend
|
|
if (!$this->app->isClient('site'))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Load Novarain Framework
|
|
if (!@include_once(JPATH_PLUGINS . '/system/nrframework/autoload.php'))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Load Plugin Helper
|
|
JLoader::register('ACFHelper', __DIR__ . '/helper/helper.php');
|
|
|
|
return ($this->init = true);
|
|
}
|
|
|
|
/**
|
|
* Let each condition check the value before it's savced into the database
|
|
*
|
|
* @param string $context
|
|
* @param object $article
|
|
* @param bool $isNew
|
|
*
|
|
* @return void
|
|
*/
|
|
public function onContentBeforeSave($context, $article, $isNew)
|
|
{
|
|
if (!in_array($context, ['com_fields.field']))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!isset($article->params))
|
|
{
|
|
return;
|
|
}
|
|
|
|
$params = json_decode($article->params, true);
|
|
if (!isset($params['rules']))
|
|
{
|
|
return;
|
|
}
|
|
|
|
NRFramework\Conditions\ConditionsHelper::getInstance()->onBeforeSave($params['rules']);
|
|
|
|
$article->params = json_encode($params);
|
|
}
|
|
}
|