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);
 | |
|     }
 | |
| }
 |