Files
conservatorio-tomadini/plugins/attachments/attachments_plugin_framework/attachments_plugin.php

1099 lines
33 KiB
PHP

<?php
/**
* Attachments for extensions
*
* @package Attachments
* @subpackage Attachments_Plugin_Framework
*
* @author Jonathan M. Cameron <jmcameron@jmcameron.net>
* @copyright Copyright (C) 2009-2018 Jonathan M. Cameron, All Rights Reserved
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
* @link http://joomlacode.org/gf/project/attachments/frs/
*/
// No direct access
defined('_JEXEC') or die('Restricted access');
/** Load the attachments helper */
require_once JPATH_SITE . '/components/com_attachments/helper.php';
/**
* Plugins for Attachments
*
* AttachmentsPlugin is the base class for all the plugins to allow
* attaching files to various types of content entities
*
* The derived attachments plugin class must be in the main PHP file for that
* plugin. For instance for content articles or categories, the parent type
* is 'com_content'. The parent type is simply the name of the component
* involved (eg, 'com_content'). The derived attachments plugin class (such
* as 'AttachmentsPlugin_com_content') should be defined in the main file for
* the plugin (eg, attachments_for_conent.php).
*
* Derived attachments plugin classes must also include the following lines of
* code after the class definition to register the derived class with the
* Attachments plugin manager:
*
* $apm = getAttachmentsPluginManager();
* $apm->addParentType('com_content');
*
* where 'com_content' should be replaced by the name of the appropriate
* parent type (component).
*
* @package Attachments
* @since 3.0
*/
class AttachmentsPlugin extends JPlugin
{
/** Parent_type: com_content, com_quickfaq, etc
*/
protected $parent_type = null;
/** Name for the default parent_entity type
*
* Note that this name will be used for a directory for attachments entries
* and should not contain any spaces. It should correspond to the default
* entity. For instance, for com_content, it will be 'article';
*/
protected $default_entity = null;
/** known entities
*/
protected $entities = null;
/** An associative array of entity names
*
* For each type of attachments plugin, there will be a default
* entity types. For com_content, the default is 'article'. If
* the $default value for the function calls below is omitted,
* the entity is assumed to be 'article'. In some cases, the
* actual proper name of the entity will be available and will be
* passed in to the $default argument. It is important that the
* plugin code recognizes that the entity 'default' is an alias
* for 'article'. This array allows a simple associative array
* lookup to transform 'default' to 'article'.
*/
protected $entity_name = Array();
/** An associative array of entity tables
*/
protected $entity_table = Array();
/** An associative array of entity id fields
* (in same table as the title)
*/
protected $entity_id_field = Array();
/** An associative array of entity title fields
*/
protected $entity_title_field = Array();
/** An associative array of parent creator user ID fields
*/
protected $parent_creator_id_field = Array();
/** Flag indicating if the language file haas been loaded
*/
protected $language_loaded = false;
/** Cache for parentExists check
*/
protected $parent_exists_cache = Array();
/** Cache for parent titles
*/
protected $title_cache = Array();
/** Cache for parameters for the com_attachments component
*/
private $com_attachments_params = null;
/**
* Constructor
*
* @param object &$subject The object to observe
* @param array $config An optional associative array of configuration settings.
* Recognized key values include 'name', 'group', 'params', 'language'
* (this list is not meant to be comprehensive).
*/
public function __construct(&$subject, $config = array())
{
parent::__construct($subject, $config);
// Save the plugin type
$this->_type = 'attachments';
}
/**
* Get the attachments parameter object
*
* @return object com_attachments parameter object
*/
public function attachmentsParams()
{
if ($this->com_attachments_params == null)
{
jimport('joomla.application.component.helper');
$this->com_attachments_params = JComponentHelper::getParams('com_attachments');
}
return $this->com_attachments_params;
}
/**
* Return the parent entity / row ID
*
* This will only be called by the main attachments 'onPrepareContent'
* plugin if $attachment ($row) does not have an id
*
* @param object &$attachment the attachment
*
* @return id if found, false if this is not a valid parent
*/
public function getParentId(&$attachment)
{
return JRequest::getInt('id', false);
}
/**
* Return the component name for this parent object
*
* @return the component name for this parent object
*/
public function getParentType()
{
return $this->parent_type;
}
/**
* Return a string of the where clause for filtering the the backend list of attachments
*
* @param string $parent_state the state ('ALL', 'PUBLISHED', 'UNPUBLISHED', 'ARCHIVED', 'NONE')
* @param string $filter_entity the entity filter ('ALL', 'ARTICLE', 'CATEGORY', etc)
*
* @return an array of (join_clause, where_clause) items
*/
public function getParentPublishedFilter($parent_state, $filter_entity)
{
return array();
}
/**
* Determine the parent entity
*
* From the view and the class of the parent (row of onPrepareContent plugin),
* determine what the entity type is for this entity.
*
* Derived classes MUST overrride this
*
* @param &object &$parent The object for the parent (row) that onPrepareContent gets
*
* @return the correct entity (eg, 'default', 'category', etc) or false if this entity should not be displayed.
*/
public function determineParentEntity(&$parent)
{
return 'default';
}
/**
* Return the name of the field with the content item text
*
* During the display of content items (eg, articles, categories), the
* onContentPrepare (etc) callbacks are used to insert attachments lists.
* The second argument of the onContentPrepare() function is an object
* (usually $row) for the content item (eg, article). This function will
* return the appropriate field for the text of the content item. In some
* cases it is 'text', in others, 'introtext'. Attachments plugins can
* override this function to provide the field name more intelligently.
*
* Note: returns null if the text field is unknown/not present.
*
* @param &object &$row the content object (eg, article) being displayed
* @param string $parent_entity the type of entity for this content item.
*
* @return string name of the text field of this content item object.
*/
protected function getTextFieldName(&$row, $parent_entity)
{
$text_field_name = null;
// Ignore items without the normal 'text' field
if (isset($row->text))
{
$text_field_name = 'text';
}
elseif (isset($row->fulltext))
{
$text_field_name = 'fulltext';
}
elseif (isset($row->introtext))
{
$text_field_name = 'introtext';
}
return $text_field_name;
}
/**
* Return the array of entity IDs for all content items supported by this parent object
*
* @return the array of entities supported by this parent object
*/
public function getEntities()
{
return $this->entities;
}
/**
* Get the default entity ID
*
* @return string the default entity ID
*/
public function getDefaultEntity()
{
return $this->default_entity;
}
/**
* Get the canonical extension entity Id (eg, 'article' instead of 'default')
*
* This is the canonical Id of content element/item to which attachments will be added.
*
* that each content type ($option) may support several different entities
* (for attachments) and some entities may have more than one name.
*
* Note, for com_content, the default is 'article'
*
* @param string $parent_entity the type of entity for this parent type
*
* @return the canonical extension entity
*/
public function getCanonicalEntityId($parent_entity)
{
// It it is a known entity, just return it
if (is_array($this->entities) && in_array($parent_entity, $this->entities))
{
return $parent_entity;
}
// Check aliases
if (is_array($this->entities) && array_key_exists($parent_entity, $this->entity_name))
{
return $this->entity_name[$parent_entity];
}
else
{
$lang = JFactory::getLanguage();
$lang->load('plg_attachments_attachments_plugin_framework', dirname(__FILE__));
$errmsg = JText::sprintf('ATTACH_ERROR_INVALID_ENTITY_S_FOR_PARENT_S', $parent_entity, $this->parent_type) . ' (ERR 300)';
JError::raiseError(500, $errmsg);
}
}
/**
* Get the path for the uploaded file (on the server file system)
*
* Note that this does not include the base directory for attachments.
*
* @param string $parent_entity the type of entity for this parent type
* @param int $parent_id the ID for the parent object
* @param int $attachment_id the ID for the attachment
*
* @return string the directory name for this entity (with trailing '/'!)
*/
public function getAttachmentPath($parent_entity, $parent_id, $attachment_id)
{
$parent_entity = $this->getCanonicalEntityId($parent_entity);
$path = sprintf("%s/%d/", $parent_entity, $parent_id);
return $path;
}
/**
* Get the name or title for the specified object
*
* @param int $parent_id the ID for this parent object
* @param string $parent_entity the type of entity for this parent type
*
* @return the name or title for the specified object
*/
public function getTitle($parent_id, $parent_entity = 'default')
{
// Short-circuit if there is no parent ID
if (!is_numeric($parent_id))
{
return '';
}
$parent_entity = $this->getCanonicalEntityId($parent_entity);
// Check the cache first
$cache_key = $parent_entity . (int) $parent_id;
if (array_key_exists($cache_key, $this->title_cache))
{
return $this->title_cache[$cache_key];
}
$entity_table = $this->entity_table[$parent_entity];
$entity_title_field = $this->entity_title_field[$parent_entity];
$entity_id_field = $this->entity_id_field[$parent_entity];
// Make sure the parent exists
if (!$this->parentExists($parent_id, $parent_entity))
{
/* Do not error out; this is most likely to occur in the backend
* when an article with attachments has been deleted without
* deleting the attachments. But we still need list it!
*/
return '';
}
// Look up the title
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select($entity_title_field)->from("#__$entity_table");
$query->where("$entity_id_field=" . (int) $parent_id);
$db->setQuery($query);
$title = $db->loadResult();
if ($db->getErrorNum())
{
$parent_entity_name = JText::_('ATTACH_' . $parent_entity);
$errmsg = JText::sprintf('ATTACH_ERROR_GETTING_PARENT_S_TITLE_FOR_ID_N',
$parent_entity_name, $parent_id) . ' (ERR 301)';
JError::raiseError(500, $errmsg);
}
$this->title_cache[$cache_key] = $title;
return $this->title_cache[$cache_key];
}
/**
* Return an array of entity items (with id,title pairs for each item)
*
* @param string $parent_entity the type of entity to search for
* @param string $filter filter the results for matches for this filter string
*
* @return the array of entity id,title pairs
*/
public function getEntityItems($parent_entity = 'default', $filter = '')
{
$parent_entity = $this->getCanonicalEntityId($parent_entity);
$entity_table = $this->entity_table[$parent_entity];
$entity_title_field = $this->entity_title_field[$parent_entity];
$entity_id_field = $this->entity_id_field[$parent_entity];
// Get the ordering information
$app = JFactory::getApplication();
$order = $app->getUserStateFromRequest('com_attachments.selectEntity.filter_order',
'filter_order', '', 'cmd');
$order_Dir = $app->getUserStateFromRequest('com_attachments.selectEntity.filter_order_Dir',
'filter_order_Dir', '', 'word');
// Get all the items
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select("DISTINCT $entity_id_field,$entity_title_field");
$query->from("#__$entity_table");
if ($filter)
{
$filter = $db->quote('%' . $db->escape($filter, true) . '%', false);
$query->where($entity_title_field . ' LIKE ' . $filter);
}
if ($order)
{
if ($order == 'title')
{
$query->order("$entity_title_field " . $order_Dir);
}
elseif ($order == 'id')
{
$query->order("$entity_id_field " . $order_Dir);
}
else
{
// Ignore unrecognized columns
}
}
// Do the query
$db->setQuery($query);
if ($db->getErrorNum())
{
$parent_entity_name = JText::_('ATTACH_' . $parent_entity);
$errmsg = JText::sprintf('ATTACH_ERROR_GETTING_LIST_OF_ENTITY_S_ITEMS', $parent_entity_name) . ' (ERR 302)';
JError::raiseError(500, $errmsg);
}
else
{
$items = $db->loadObjectList();
}
if ($items == null)
{
return null;
}
// Make sure the the ids are called 'id' in the list
if ($entity_id_field != 'id')
{
foreach ($items as $item)
{
$item->id = $item->$entity_id_field;
}
}
// Make sure the the titles are called 'title' in the list
if ($entity_title_field != 'title')
{
foreach ($items as $item)
{
$item->title = $item->$entity_title_field;
}
}
return $items;
}
/**
* Return the URL that can be called to select a specific content item.
*
* @param string $parent_entity the type of entity to select from
*
* @return the URL that can be called to select a specific content item
*/
public function getSelectEntityURL($parent_entity = 'default')
{
// Add on the parent type and entity
$entity = "&amp;parent_type=" . $this->parent_type;
if ($parent_entity != 'default')
{
$entity .= '.' . $parent_entity;
}
return "index.php?option=com_attachments&amp;task=selectEntity" . $entity . "&amp;tmpl=component";
}
/**
* Return the ID of the creator/owner of the parent entity
*
* @param int $parent_id the ID for the parent object
* @param string $parent_entity the type of entity for this parent type
*
* @return creators id if found, 0 otherwise
*/
public function getParentCreatorId($parent_id, $parent_entity = 'default')
{
JError::raiseError(501, JText::_('ATTACH_NOT_IMPLEMENTED'));
}
/**
* Get a URL to view the entity
*
* @param int $parent_id the ID for this parent object
* @param string $parent_entity the type of entity for this parent type
*
* @return a URL to view the entity (non-SEF form)
*/
public function getEntityViewURL($parent_id, $parent_entity = 'default')
{
return null;
}
/**
* Get a URL to add an attachment to a specific entity
*
* @param int $parent_id the ID for the parent entity object (null if the parent does not exist)
* @param string $parent_entity the type of entity for this parent type
* @param string $from where the call should return to
*
* @return the url to add a new attachments to the specified entity
*/
public function getEntityAddUrl($parent_id, $parent_entity = 'default', $from = 'closeme')
{
$app = JFactory::getApplication();
if ($app->isAdmin())
{
$task = 'add';
}
else
{
$task = 'upload';
}
$url = "index.php?option=com_attachments&task=$task";
if ($parent_id == null)
{
$url .= "&parent_id=$parent_id,new";
}
else
{
$url .= "&parent_id=$parent_id";
}
$url .= "&parent_type=" . $this->parent_type . "&from=$from";
return $url;
}
/**
* Check to see if a custom title applies to this parent
*
* Note: this public function assumes that the parent_id's match
*
* @param string $parent_entity the parent entity for the parent of the list
* @param string $rtitle_parent_entity the entity of the candidate attachment list title (from params)
*
* @return true if the custom title should be used
*/
public function checkAttachmentsListTitle($parent_entity, $rtitle_parent_entity)
{
return false;
}
/**
* Get the title for the attachments list for this parent
*
* @param string $title the untranslated title token (either 'ATTACH_ATTACHMENTS_TITLE' or 'ATTACH_EXISTING_ATTACHMENTS')
* @param int $parent_id the ID for the parent entity object (null if the parent does not exist)
* @param string $parent_entity the type of entity for this parent type
*
* @return the translated title string
*/
public function attachmentsListTitle($title, $parent_id, $parent_entity = 'default')
{
$aparams = $this->attachmentsParams();
$rtitle_str = $aparams->get('attachments_titles', '');
if (($title != 'ATTACH_EXISTING_ATTACHMENTS') && ($rtitle_str != ''))
{
$rtitle_list = preg_split("[\n|\r]", $rtitle_str);
foreach ($rtitle_list as $rtitle)
{
if (preg_match('|^([0-9]+)\s*([^$]+)$|', $rtitle, $match))
{
// Process: 3 new title
// NOTE: This form only applies to articles and will be ignored for anything else
if ((int) $parent_id != (int) $match[1])
{
continue;
}
if (($this->parent_type == 'com_content') && (($parent_entity == 'default') || ($parent_entity == 'article')))
{
$title = $match[2];
}
}
elseif (preg_match('|^([a-zA-Z0-9_/-]+):([0-9]+)\s*([^$]+)$|', $rtitle, $match))
{
// Process: entity:3 new title
if ((int) $parent_id != (int) $match[2])
{
continue;
}
if ($this->checkAttachmentsListTitle($parent_entity, $match[1]))
{
$title = $match[3];
}
}
else
{
// With no entity/numeric prefix, the title applies to all attachments lists
$rtitle = trim($rtitle);
if ($rtitle != '')
{
$title = $rtitle;
}
}
}
}
return JText::_($title);
}
/**
* Does the parent exist?
*
* @param int $parent_id the ID for this parent object
* @param string $parent_entity the type of entity for this parent type
*
* @return true if the parent exists
*/
public function parentExists($parent_id, $parent_entity = 'default')
{
$parent_entity = $this->getCanonicalEntityId($parent_entity);
// Check the cache first
$cache_key = $parent_entity . (int) $parent_id;
if (array_key_exists($cache_key, $this->parent_exists_cache))
{
return $this->parent_exists_cache[$cache_key];
}
// First time, so look up the parent
$entity_table = $this->entity_table[$parent_entity];
$entity_id_field = $this->entity_id_field[$parent_entity];
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select($entity_id_field)->from("#__$entity_table");
$query->where("$entity_id_field=" . (int) $parent_id);
$db->setQuery($query, 0, 1);
$result = $db->loadResult();
if ($result === null)
{
$this->parent_exists_cache[$cache_key] = false;
}
else
{
$this->parent_exists_cache[$cache_key] = (int) $parent_id == (int) $result;
}
return $this->parent_exists_cache[$cache_key];
}
/**
* Is the parent new (based on the parent_id)
*
* @param object &$attachment the attachment
*
* @return true if the parent is new (being created)
*/
public function newParent(&$attachment)
{
// Assume parent_id == 0 means the parent is new
// (NOTE: This may not be true for some components)
return $attachment->parent_id == 0;
}
/**
* Check to see if the parent is published
*
* @param int $parent_id the ID for this parent object
* @param string $parent_entity the type of entity for this parent type
*
* @return true if the parent is published
*/
public function isParentPublished($parent_id, $parent_entity = 'default')
{
return false;
}
/**
* Check to see if the parent is archived
*
* @param int $parent_id the ID for this parent object
* @param string $parent_entity the type of entity for this parent type
*
* @return true if the parent is archived
*/
public function isParentArchived($parent_id, $parent_entity = 'default')
{
return false;
}
/**
* May the parent be viewed by the user?
*
* This public function should be called by derived class functions.
*
* Note that this base class function only determines necessary
* conditions. If this function returns FALSE, then viewing is definitely
* not permitted. If this function returns TRUE, then the derived classes
* also need to check whether viewing the specific content item (eg,
* article) is permitted.
*
* @param int $parent_id the ID for this parent object
* @param string $parent_entity the type of entity for this parent type
* @param object $user_id the user_id to check (optional, primarily for testing)
*
* @return true if the parent may be viewed by the user
*/
public function userMayViewParent($parent_id, $parent_entity = 'default', $user_id = null)
{
JError::raiseError(501, JText::_('ATTACH_NOT_IMPLEMENTED'));
}
/** Return true if the attachments should be hidden for this parent
*
* @param &object &$parent the object for the parent that onPrepareContent gives
* @param int $parent_id the ID of the parent the attachment is attached to
* @param string $parent_entity the type of entity for this parent type
*
* Note: this generic version only implements the 'frontpage' option. All
* other options should be handled by the derived classes for other
* content types.
*
* @return true if the attachments should be hidden for this parent
*/
public function attachmentsHiddenForParent(&$parent, $parent_id, $parent_entity)
{
$layout = JRequest::getCmd('layout');
$aparams = $this->attachmentsParams();
// Check to see whether the attachments should be hidden on the front page
$hide_on_frontpage = $aparams->get('hide_on_frontpage', false);
if ($hide_on_frontpage && (JRequest::getVar('view') == 'featured'))
{
return true;
}
// Hide on blog pages?
$hide_on_blogs = $aparams->get('hide_on_blogs', false);
if ($hide_on_blogs && ($layout == 'blog'))
{
return true;
}
return false;
}
/**
* Return true if the user may add an attachment to this parent
*
* (Note that all of the arguments are assumed to be valid; no sanity checking is done.
* It is up to the caller to validate these objects before calling this function.)
*
* @param int $parent_id the ID of the parent the attachment is attached to
* @param string $parent_entity the type of entity for this parent type
* @param bool $new_parent if true, the parent is being created and does not exist yet
* @param object $user_id the user_id to check (optional, primarily for testing)
*
* @return true if this user add attachments to this parent
*/
public function userMayAddAttachment($parent_id, $parent_entity, $new_parent = false, $user_id = null)
{
JError::raiseError(501, JText::_('ATTACH_NOT_IMPLEMENTED'));
}
/**
* Return true if this user may edit (modify/delete/update) this attachment for this parent
*
* (Note that all of the arguments are assumed to be valid; no sanity checking is done.
* It is up to the caller to validate the arguments before calling this function.)
*
* @param &record &$attachment database record for the attachment
* @param object $user_id the user_id to check (optional, primarily for testing)
*
* @return true if this user may edit this attachment
*/
public function userMayEditAttachment(&$attachment, $user_id = null)
{
JError::raiseError(501, JText::_('ATTACH_NOT_IMPLEMENTED'));
}
/**
* Return true if this user may delete this attachment for this parent
*
* (Note that all of the arguments are assumed to be valid; no sanity checking is done.
* It is up to the caller to validate the arguments before calling this function.)
*
* @param &record &$attachment database record for the attachment
* @param object $user_id the user_id to check (optional, primarily for testing)
*
* @return true if this user may delete this attachment
*/
public function userMayDeleteAttachment(&$attachment, $user_id = null)
{
JError::raiseError(501, JText::_('ATTACH_NOT_IMPLEMENTED'));
}
/**
* Return true if this user may change the state of this attachment
*
* (Note that all of the arguments are assumed to be valid; no sanity checking is done.
* It is up to the caller to validate the arguments before calling this function.)
*
* @param int $parent_id the ID for the parent object
* @param string $parent_entity the type of entity for this parent type
* @param int $attachment_creator_id the ID of the creator of the attachment
* @param object $user_id the user_id to check (optional, primarily for testing)
*
* @return true if this user may change the state of this attachment
*/
public function userMayChangeAttachmentState($parent_id, $parent_entity, $attachment_creator_id, $user_id = null)
{
JError::raiseError(501, JText::_('ATTACH_NOT_IMPLEMENTED'));
}
/** Check to see if the user may access (see/download) the attachments
*
* @param &record &$attachment database record for the attachment
* @param object $user_id the user_id to check (optional, primarily for testing)
*
* @return true if access is okay (false if not)
*/
public function userMayAccessAttachment(&$attachment, $user_id = null)
{
JError::raiseError(501, JText::_('ATTACH_NOT_IMPLEMENTED'));
}
/** Insert the attachments list into the content text (for front end)
*
* @param object &$content the text of the content item (eg, article text)
* @param int $parent_id the ID for the parent object
* @param string $parent_entity the type of entity for this parent type
*
* @return string the modified content text (false for failure)
*/
public function insertAttachmentsList(&$content, $parent_id, $parent_entity)
{
$aparams = $this->attachmentsParams();
// Get the desired placement
$attachments_placement = $aparams->get('attachments_placement', 'end');
if ($attachments_placement == 'disabled_nofilter')
{
return false;
}
// Determine where we are
$from = JRequest::getCmd('view', 'closeme');
$Itemid = JRequest::getInt('Itemid', 1);
// See whether we can display the links to add attachments
$user_can_add = $this->userMayAddAttachment($parent_id, $parent_entity);
// Get the field name for the content item's text
$text_field_name = $this->getTextFieldName($content, $parent_entity);
if ($text_field_name === null)
{
return false;
}
// Get the attachments tag, if present
$attachments_tag = '';
$attachments_tag_args = '';
$match = false;
if (JString::strpos($content->$text_field_name, '{attachments'))
{
if (preg_match('@(<span class="hide_attachments_token">)?{attachments([ ]*:*[^}]+)?}(</span>)?@', $content->$text_field_name, $match))
{
$attachments_tag = true;
}
if (isset($match[1]) && $match[1])
{
$attachments_tag_args_raw = $match[1];
$attachments_tag_args = ltrim($attachments_tag_args_raw, ' :');
}
if ($attachments_tag)
{
$attachments_tag = $match[0];
}
}
// Check the security status
$attach_dir = JPATH_SITE . '/' . AttachmentsDefines::$ATTACHMENTS_SUBDIR;
$secure = $aparams->get('secure', false);
$hta_filename = $attach_dir . '/ . htaccess';
if (($secure && !file_exists($hta_filename)) || (!$secure && file_exists($hta_filename)))
{
AttachmentsHelper::setup_upload_directory($attach_dir, $secure);
}
// Construct the attachment list (if appropriate)
$html = '';
$attachments_list = false;
$add_attachement_btn = false;
// Get the html for the attachments list
require_once JPATH_SITE . '/components/com_attachments/controllers/attachments.php';
$controller = new AttachmentsControllerAttachments;
$attachments_list = $controller->displayString($parent_id, $this->parent_type, $parent_entity, null, true, true, false, $from);
// If the attachments list is empty, insert an empty div for it
if ($attachments_list == '')
{
$class_name = $aparams->get('attachments_table_style', 'attachmentsList');
$div_id = 'attachmentsList' . '_' . $this->parent_type . '_' . $parent_entity . '_' . (string) $parent_id;
$attachments_list = "\n<div class=\"$class_name\" id=\"$div_id\"></div>\n";
}
$html .= $attachments_list;
if ($html || $user_can_add)
{
// Add the style sheet
JHtml::stylesheet('com_attachments/attachments_list.css', Array(), true);
// Handle RTL styling (if necessary)
$lang = JFactory::getLanguage();
if ($lang->isRTL())
{
JHtml::stylesheet('com_attachments/attachments_list_rtl.css', Array(), true);
}
}
// Construct the add-attachments button, if appropriate
$hide_add_attachments_link = $aparams->get('hide_add_attachments_link', 0);
if ($user_can_add && !$hide_add_attachments_link)
{
$add_attachments_btn = AttachmentsHelper::attachmentButtonsHTML($this->parent_type, $parent_id, $parent_entity, $Itemid, $from);
$html .= $add_attachments_btn;
}
// Wrap both list and the Add Attachments button in another div
if ($html)
{
$html = "<div class=\"attachmentsContainer\">\n" . $html . "\n</div>";
}
// Finally, add the attachments
// NOTE: Hope str_replace() below is UTF8 safe (since the token being replaced is UTF8)...
switch ($attachments_placement)
{
case 'beginning':
// Put the attachments list at the beginning
if ($attachments_list || $user_can_add)
{
if ($attachments_tag)
{
$content->$text_field_name = $html . $content->$text_field_name;
}
else
{
$content->$text_field_name = $html . str_replace($attachments_tag, '', $content->$text_field_name);
}
}
break;
case 'custom':
// Insert the attachments at the desired location
if ($attachments_list || $user_can_add)
{
if ($attachments_tag)
{
$content->$text_field_name = str_replace($attachments_tag, $html, $content->$text_field_name);
}
else
{
// If there is no tag, insert the attachments at the end
$content->$text_field_name .= $html;
}
}
break;
case 'disabled_filter':
// Disable and strip out any attachments tags
if ($attachments_tag)
{
$content->$text_field_name = str_replace($attachments_tag, '', $content->$text_field_name);
}
break;
default:
// Add the attachments to the end
if ($attachments_list || $user_can_add)
{
if ($attachments_tag)
{
$content->$text_field_name = str_replace($attachments_tag, '', $content->$text_field_name) . $html;
}
else
{
$content->$text_field_name .= $html;
}
}
break;
}
return $content;
}
/** Get the parent_id in the component content item editor
* (the article or category editor)
*
* @param string $parent_entity the type of entity for this parent type
*
* @return the parent ID, null if the content item is being created, and false if there is no match
*
* @since Attachments 3.2
*/
public function getParentIdInEditor($parent_entity, $view, $layout)
{
// This should work in the backend for most well-implemented content types--
// but not for all frontends, especially not com_content/articles
$id = null;
if ($view == $parent_entity) {
$id = JRequest::getInt('id', $default=null);
}
else {
$id = false;
}
// If we got one, convert it to an int
if (is_numeric($id)) {
$id = (int)$id;
}
return $id;
}
/** See if the attachments list should be displayed in its content description editor
*
* @param string $parent_entity the type of entity for this parent type
* @param string $view the view
* @param string $layout the layout on the view
*
* @return true if the attachments list should be added to the editor
*/
public function showAttachmentsInEditor($parent_entity, $view, $layout)
{
JError::raiseError(501, JText::_('ATTACH_NOT_IMPLEMENTED'));
}
/** Insert the attachments list into the entity editor page
*
* @param int $parent_id the ID for the parent object
* @param string $parent_entity the type of entity for this parent type
* @param string $attachments the attachments list as a string
* @param string $body the editor page text
*
* @return string the modified editor page text (false for failure)
*/
public function insertAttachmentsListInEditor($parent_id, $parent_entity, $attachments, $body)
{
// Figure out where to insert the attachments list
$reptag = '<div id="editor-xtd-buttons"';
if (version_compare(JVERSION, '3.5', 'ge')) {
if (JFactory::getEditor()->get('_name') == 'tinymce') {
# Hack because TinyMCE changed the structure
$reptag = '<div class="toggle-editor btn-toolbar pull-right clearfix"';
}
}
// Insert the attachments above the editor buttons
// NOTE: Assume that anyone editing the entity can see its attachments
$body = str_replace($reptag, $attachments . $reptag, $body);
return $body;
}
/** Known from keywords
*
* Attachment pop-dialogs will be closed using javascript if they are called from pages of these 'from' types
*
* @retrun array An array of known tokens (strings)
*/
public function knownFroms()
{
// Most components should recognize these
return Array('editor', 'closeme');
}
}