581 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			581 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * Attachment list model definition
 | |
|  *
 | |
|  * @package Attachments
 | |
|  * @subpackage Attachments_Component
 | |
|  *
 | |
|  * @copyright Copyright (C) 2007-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/
 | |
|  * @author Jonathan M. Cameron
 | |
|  */
 | |
| 
 | |
| defined('_JEXEC') or die('Restricted access');
 | |
| 
 | |
| jimport('joomla.application.component.helper');
 | |
| 
 | |
| /** Define the legacy classes, if necessary */
 | |
| require_once(JPATH_SITE.'/components/com_attachments/legacy/model.php');
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * Attachment List Model for all attachments belonging to one
 | |
|  * content article (or other content-related entity)
 | |
|  *
 | |
|  * @package Attachments
 | |
|  */
 | |
| class AttachmentsModelAttachments extends JModelLegacy
 | |
| {
 | |
| 	/**
 | |
| 	 * ID of parent of the list of attachments
 | |
| 	 */
 | |
| 	var $_parent_id = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * type of parent
 | |
| 	 */
 | |
| 	var $_parent_type = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * type of parent entity (each parent_type can support several)
 | |
| 	 */
 | |
| 	var $_parent_entity = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Parent class object (an Attachments extension plugin object)
 | |
| 	 */
 | |
| 	var $_parent = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Parent title
 | |
| 	 */
 | |
| 	var $_parent_title = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Parent entity name
 | |
| 	 */
 | |
| 	var $_parent_entity_name = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Whether some of the attachments should be visible to the user
 | |
| 	 */
 | |
| 	var $_some_visible = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Whether some of the attachments should be modifiable to the user
 | |
| 	 */
 | |
| 	var $_some_modifiable = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * The desired sort order
 | |
| 	 */
 | |
| 	var $_sort_order;
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * The list of attachments for the specified article/content entity
 | |
| 	 */
 | |
| 	var $_list = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Number of attachments
 | |
| 	 *
 | |
| 	 * NOTE: After the list of attachments has been retrieved, if it is empty, this is set to zero.
 | |
| 	 *		 But _list remains null.   You can use this to check to see if the list has been loaded.
 | |
| 	 */
 | |
| 	var $_num_attachments = null;
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * Constructor
 | |
| 	 */
 | |
| 	public function __construct()
 | |
| 	{
 | |
| 		parent::__construct();
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * Set the parent id (and optionally the parent type)
 | |
| 	 *
 | |
| 	 * NOTE: If the $id is null, it will get both $id and $parent_id from JRequest
 | |
| 	 *
 | |
| 	 * @param int $id the id of the parent
 | |
| 	 * @param string $parent_type the parent type (defaults to 'com_content')
 | |
| 	 * @param string $parent_entity the parent entity (defaults to 'default')
 | |
| 	 */
 | |
| 	public function setParentId($id=null, $parent_type='com_content', $parent_entity='default')
 | |
| 	{
 | |
| 		// Get the parent id and type
 | |
| 		if ( is_numeric($id) ) {
 | |
| 			$parent_id = (int)$id;
 | |
| 			}
 | |
| 		else {
 | |
| 			// It was not an argument, so get parent id and type from the JRequest
 | |
| 			$parent_id	 = JRequest::getInt('article_id', null);
 | |
| 
 | |
| 			// Deal with special case of editing from the front end
 | |
| 			if ( $parent_id == null ) {
 | |
| 				if ( (JRequest::getCmd('view') == 'article') &&
 | |
| 					 (JRequest::getCmd('task') == 'edit' )) {
 | |
| 					$parent_id = JRequest::getInt('id', null);
 | |
| 					}
 | |
| 				}
 | |
| 
 | |
| 			// If article_id is not specified, get the general parent id/type
 | |
| 			if ( $parent_id == null ) {
 | |
| 				$parent_id = JRequest::getInt('parent_id', null);
 | |
| 				if ( $parent_id == null ) {
 | |
| 					$errmsg = JText::_('ATTACH_ERROR_NO_PARENT_ID_SPECIFIED') . ' (ERR 50)';
 | |
| 					JError::raiseError(500, $errmsg);
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 		// Reset instance variables
 | |
| 		$this->_parent_id = $parent_id;
 | |
| 		$this->_parent_type = $parent_type;
 | |
| 		$this->_parent_entity = $parent_entity;
 | |
| 
 | |
| 		$this->_parent = null;
 | |
| 		$this->_parent_class = null;
 | |
| 		$this->_parent_title = null;
 | |
| 		$this->_parent_entity_name = null;
 | |
| 
 | |
| 		$this->_list = null;
 | |
| 		$this->_sort_order = null;
 | |
| 		$this->_some_visible = null;
 | |
| 		$this->_some_modifiable = null;
 | |
| 		$this->_num_attachments = null;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * Get the parent id
 | |
| 	 *
 | |
| 	 * @return the parent id
 | |
| 	 */
 | |
| 	public function getParentId()
 | |
| 	{
 | |
| 		if ( $this->_parent_id === null ) {
 | |
| 			$errmsg = JText::_('ATTACH_ERROR_NO_PARENT_ID_SPECIFIED') . ' (ERR 51)';
 | |
| 			JError::raiseError(500, $errmsg);
 | |
| 			}
 | |
| 		return $this->_parent_id;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * Get the parent type
 | |
| 	 *
 | |
| 	 * @return the parent type
 | |
| 	 */
 | |
| 	public function getParentType()
 | |
| 	{
 | |
| 		if ( $this->_parent_type == null ) {
 | |
| 			$errmsg = JText::_('ATTACH_ERROR_NO_PARENT_TYPE_SPECIFIED') . ' (ERR 52)';
 | |
| 			throw Exception($errmsg);
 | |
| 			// JError::raiseError(500, $errmsg);
 | |
| 			}
 | |
| 		return $this->_parent_type;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * Get the parent entity
 | |
| 	 *
 | |
| 	 * @return the parent entity
 | |
| 	 */
 | |
| 	public function getParentEntity()
 | |
| 	{
 | |
| 		if ( $this->_parent_entity == null ) {
 | |
| 			$errmsg = JText::_('ATTACH_ERROR_NO_PARENT_ENTITY_SPECIFIED') . ' (ERR 53)';
 | |
| 			JError::raiseError(500, $errmsg);
 | |
| 			}
 | |
| 
 | |
| 		// Make sure we have a good parent_entity value
 | |
| 		if ( $this->_parent_entity == 'default' ) {
 | |
| 			$parent = $this->getParentClass();
 | |
| 			$this->_parent_entity = $parent->getDefaultEntity();
 | |
| 			}
 | |
| 
 | |
| 		return $this->_parent_entity;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * Get the parent class object
 | |
| 	 *
 | |
| 	 * @return the parent class object
 | |
| 	 */
 | |
| 	public function &getParentClass()
 | |
| 	{
 | |
| 		if ( $this->_parent_type == null ) {
 | |
| 			$errmsg = JText::_('ATTACH_ERROR_NO_PARENT_TYPE_SPECIFIED') . ' (ERR 54)';
 | |
| 			JError::raiseError(500, $errmsg);
 | |
| 			}
 | |
| 
 | |
| 		if ( $this->_parent_class == null ) {
 | |
| 
 | |
| 			// Get the parent handler
 | |
| 			JPluginHelper::importPlugin('attachments');
 | |
| 			$apm = getAttachmentsPluginManager();
 | |
| 			if ( !$apm->attachmentsPluginInstalled($this->_parent_type) ) {
 | |
| 				$errmsg = JText::sprintf('ATTACH_ERROR_INVALID_PARENT_TYPE_S', $parent_type) . ' (ERR 55)';
 | |
| 				JError::raiseError(500, $errmsg);
 | |
| 				}
 | |
| 			$this->_parent_class = $apm->getAttachmentsPlugin($this->_parent_type);
 | |
| 			}
 | |
| 
 | |
| 		return $this->_parent_class;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * Get the title for the parent
 | |
| 	 *
 | |
| 	 * @return the title for the parent
 | |
| 	 */
 | |
| 	public function getParentTitle()
 | |
| 	{
 | |
| 		// Get the title if we have not done it before
 | |
| 		if ( $this->_parent_title == null ) {
 | |
| 
 | |
| 			$parent = $this->getParentClass();
 | |
| 
 | |
| 			// Make sure we have an article ID
 | |
| 			if ( $this->_parent_id === null ) {
 | |
| 				$errmsg = JText::_('ATTACH_ERROR_UNKNOWN_PARENT_ID') . ' (ERR 56)';
 | |
| 				JError::raiseError(500, $errmsg);
 | |
| 				}
 | |
| 
 | |
| 			$this->_parent_title = $parent->getTitle( $this->_parent_id, $this->_parent_entity );
 | |
| 			}
 | |
| 
 | |
| 		return $this->_parent_title;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * Get the EntityName for the parent
 | |
| 	 *
 | |
| 	 * @return the entity name for the parent
 | |
| 	 */
 | |
| 	public function getParentEntityName()
 | |
| 	{
 | |
| 		// Get the parent entity name if we have not done it before
 | |
| 		if ( $this->_parent_entity_name == null ) {
 | |
| 
 | |
| 			// Make sure we have an article ID
 | |
| 			if ( $this->_parent_id === null ) {
 | |
| 				$errmsg = JText::_('ATTACH_ERROR_NO_PARENT_ID_SPECIFIED') . ' (ERR 57)';
 | |
| 				JError::raiseError(500, $errmsg);
 | |
| 				}
 | |
| 
 | |
| 			$this->_parent_entity_name = JText::_('ATTACH_' . $this->getParentEntity());
 | |
| 			}
 | |
| 
 | |
| 		return $this->_parent_entity_name;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * Set the sort order (do this before doing getAttachmentsList)
 | |
| 	 *
 | |
| 	 * @param string $new_sort_order name of the new sort order
 | |
| 	 */
 | |
| 	public function setSortOrder($new_sort_order)
 | |
| 	{
 | |
| 		if ( $new_sort_order == 'filename' )
 | |
| 			$order_by = 'filename';
 | |
| 		else if ( $new_sort_order == 'filename_desc' )
 | |
| 			$order_by = 'filename DESC';
 | |
| 		else if ( $new_sort_order == 'file_size' )
 | |
| 			$order_by = 'file_size';
 | |
| 		else if ( $new_sort_order == 'file_size_desc' )
 | |
| 			$order_by = 'file_size DESC';
 | |
| 		else if ( $new_sort_order == 'description' )
 | |
| 			$order_by = 'description';
 | |
| 		else if ( $new_sort_order == 'description_desc' )
 | |
| 			$order_by = 'description DESC';
 | |
| 		else if ( $new_sort_order == 'display_name' )
 | |
| 			$order_by = 'display_name, filename';
 | |
| 		else if ( $new_sort_order == 'display_name_desc' )
 | |
| 			$order_by = 'display_name DESC, filename';
 | |
| 		else if ( $new_sort_order == 'created' )
 | |
| 			$order_by = 'created';
 | |
| 		else if ( $new_sort_order == 'created_desc' )
 | |
| 			$order_by = 'created DESC';
 | |
| 		else if ( $new_sort_order == 'modified' )
 | |
| 			$order_by = 'modified';
 | |
| 		else if ( $new_sort_order == 'modified_desc' )
 | |
| 			$order_by = 'modified DESC';
 | |
| 		else if ( $new_sort_order == 'user_field_1' )
 | |
| 			$order_by = 'user_field_1';
 | |
| 		else if ( $new_sort_order == 'user_field_1_desc' )
 | |
| 			$order_by = 'user_field_1 DESC';
 | |
| 		else if ( $new_sort_order == 'user_field_2' )
 | |
| 			$order_by = 'user_field_2';
 | |
| 		else if ( $new_sort_order == 'user_field_2_desc' )
 | |
| 			$order_by = 'user_field_2 DESC';
 | |
| 		else if ( $new_sort_order == 'user_field_3' )
 | |
| 			$order_by = 'user_field_3';
 | |
| 		else if ( $new_sort_order == 'user_field_3_desc' )
 | |
| 			$order_by = 'user_field_3 DESC';
 | |
| 		else if ( $new_sort_order == 'id' )
 | |
| 			$order_by = 'id';
 | |
| 		else
 | |
| 			$order_by = 'filename';
 | |
| 
 | |
| 		$this->_sort_order = $order_by;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * Get or build the list of attachments
 | |
| 	 *
 | |
| 	 * @return the list of attachments for this parent
 | |
| 	 */
 | |
| 	public function &getAttachmentsList()
 | |
| 	{
 | |
| 		// Just return it if it has already been created
 | |
| 		if ( $this->_list != null ) {
 | |
| 			return $this->_list;
 | |
| 			}
 | |
| 
 | |
| 		// Get the component parameters
 | |
| 		$params = JComponentHelper::getParams('com_attachments');
 | |
| 
 | |
| 		// Create the list
 | |
| 
 | |
| 		// Get the parent id and type
 | |
| 		$parent_id	   = $this->getParentId();
 | |
| 		$parent_type   = $this->getParentType();
 | |
| 		$parent_entity = $this->getParentEntity();
 | |
| 
 | |
| 		// Use parent entity corresponding to values saved in the attachments table
 | |
| 		$parent = $this->getParentClass();
 | |
| 
 | |
| 		// Define the list order
 | |
| 		if ( ! $this->_sort_order ) {
 | |
| 			$this->_sort_order = 'filename';
 | |
| 			}
 | |
| 
 | |
| 		// Determine allowed access levels
 | |
| 		$db = JFactory::getDBO();
 | |
| 		$user = JFactory::getUser();
 | |
| 		$user_levels = $user->getAuthorisedViewLevels();
 | |
| 
 | |
| 		// If the user is not logged in, add extra view levels (if configured)
 | |
| 		$secure = $params->get('secure', false);
 | |
| 		$logged_in = $user->get('username') <> '';
 | |
| 		if ( !$logged_in AND $secure ) {
 | |
| 			$user_levels = Array('1'); // Override the authorised levels
 | |
| 			// NOTE: Public attachments are ALWAYS visible
 | |
| 			$guest_levels = $params->get('show_guest_access_levels', Array());
 | |
| 			if (is_array($guest_levels)) {
 | |
| 				foreach ($guest_levels as $glevel) {
 | |
| 					$user_levels[] = $glevel;
 | |
| 					}
 | |
| 				}
 | |
| 			else {
 | |
| 				$user_levels[] = $glevel;
 | |
| 				}
 | |
| 			}
 | |
| 		$user_levels = implode(',', array_unique($user_levels));
 | |
| 
 | |
| 		// Create the query
 | |
| 		$query = $db->getQuery(true);
 | |
| 		$query->select('a.*, u.name as creator_name')->from('#__attachments AS a');
 | |
| 		$query->leftJoin('#__users AS u ON u.id = a.created_by');
 | |
| 
 | |
| 		if ( $parent_id == 0 ) {
 | |
| 			// If the parent ID is zero, the parent is being created so we have
 | |
| 			// do the query differently
 | |
| 			$user_id = $user->get('id');
 | |
| 			$query->where('a.parent_id IS NULL AND u.id=' . (int)$user_id);
 | |
| 			}
 | |
| 		else {
 | |
| 			$query->where('a.parent_id='.(int)$parent_id);
 | |
| 
 | |
| 			// Handle the state part of the query
 | |
| 			if ( $user->authorise('core.edit.state', 'com_attachments') ) {
 | |
| 				// Do not filter on state since this user can change the state of any attachment
 | |
| 				}
 | |
| 			elseif ( $user->authorise('attachments.edit.state.own', 'com_attachments') ) {
 | |
| 				$query->where('((a.created_by = '.(int)$user->id.') OR (a.state = 1))');
 | |
| 				}
 | |
| 			elseif ( $user->authorise('attachments.edit.state.ownparent', 'com_attachments') ) {
 | |
| 				// The user can edit the state of any attachment if they created the article/parent
 | |
| 				$parent_creator_id = $parent->getParentCreatorId($parent_id, $parent_entity);
 | |
| 				if ( (int)$parent_creator_id == (int)$user->get('id') ) {
 | |
| 					// Do not filter on state since this user can change the state of any attachment on this article/parent
 | |
| 					}
 | |
| 				else {
 | |
| 					// Since the user is not the creator, they should only see published attachments
 | |
| 					$query->where('a.state = 1');
 | |
| 					}
 | |
| 				}
 | |
| 			else {
 | |
| 				// For everyone else only show published attachments
 | |
| 				$query->where('a.state = 1');
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 		$query->where('a.parent_type=' . $db->quote($parent_type) . ' AND a.parent_entity=' . $db->quote($parent_entity));
 | |
| 		if ( !$user->authorise('core.admin') ) {
 | |
| 			$query->where('a.access IN ('.$user_levels.')');
 | |
| 			}
 | |
| 		$query->order($this->_sort_order);
 | |
| 
 | |
| 		// Do the query
 | |
| 		$db->setQuery($query);
 | |
| 		$attachments = $db->loadObjectList();
 | |
| 		if ( $db->getErrorNum() ) {
 | |
| 			$errmsg = $db->stderr() . ' (ERR 58)';
 | |
| 			JError::raiseError(500, $errmsg);
 | |
| 			}
 | |
| 
 | |
| 		$this->_some_visible = false;
 | |
| 		$this->_some_modifiable = false;
 | |
| 
 | |
| 		// Install the list of attachments in this object
 | |
| 		$this->_num_attachments = count($attachments);
 | |
| 
 | |
| 		// The query only returns items that are visible/accessible for
 | |
| 		// the user, so if it contains anything, they will be visible
 | |
| 		$this->_some_visible = $this->_num_attachments > 0;
 | |
| 
 | |
| 		// Add permissions for each attachment in the list
 | |
| 		if ( $this->_num_attachments > 0 ) {
 | |
| 
 | |
| 			$this->_list = $attachments;
 | |
| 
 | |
| 			// Add the permissions to each row
 | |
| 			$parent = $this->getParentClass();
 | |
| 
 | |
| 			// Add permissions
 | |
| 			foreach ( $attachments as $attachment ) {
 | |
| 				$attachment->user_may_delete = $parent->userMayDeleteAttachment($attachment);
 | |
| 				$attachment->user_may_edit = $parent->userMayEditAttachment($attachment);
 | |
| 				if ( $attachment->user_may_edit ) {
 | |
| 					$this->_some_modifiable = true;
 | |
| 					}
 | |
| 				}
 | |
| 
 | |
| 			// Fix relative URLs
 | |
| 			foreach ( $attachments as $attachment ) {
 | |
| 				if ( $attachment->uri_type == 'url' ) {
 | |
| 					$url = $attachment->url;
 | |
| 					if ( strpos($url, '://') === false ) {
 | |
| 						$uri = JFactory::getURI();
 | |
| 						$attachment->url = $uri->base(true) . '/' . $url;
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 
 | |
| 			}
 | |
| 
 | |
| 		// Finally, return the list!
 | |
| 		return $this->_list;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * Get the number of attachments
 | |
| 	 *
 | |
| 	 * @return the number of attachments for this parent
 | |
| 	 */
 | |
| 	public function numAttachments()
 | |
| 	{
 | |
| 		return $this->_num_attachments;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * Are some of the attachments be visible?
 | |
| 	 *
 | |
| 	 * @return true if there are attachments and some should be visible
 | |
| 	 */
 | |
| 	public function someVisible()
 | |
| 	{
 | |
| 		// See if the attachments list has been loaded
 | |
| 		if ( $this->_list == null ) {
 | |
| 
 | |
| 			// See if we have already loaded the attachements list
 | |
| 			if ( $this->_num_attachments === 0 ) {
 | |
| 				return false;
 | |
| 				}
 | |
| 
 | |
| 			// Since the attachments have not been loaded, load them now
 | |
| 			$this->getAttachmentsList();
 | |
| 			}
 | |
| 
 | |
| 		return $this->_some_visible;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * Should some of the attachments be modifiable?
 | |
| 	 *
 | |
| 	 * @return true if there are attachments and some should be modifiable
 | |
| 	 */
 | |
| 	public function someModifiable()
 | |
| 	{
 | |
| 		// See if the attachments list has been loaded
 | |
| 		if ( $this->_list == null ) {
 | |
| 
 | |
| 			// See if we have already loaded the attachements list
 | |
| 			if ( $this->_num_attachments === 0 ) {
 | |
| 				return false;
 | |
| 				}
 | |
| 
 | |
| 			// Since the attachments have not been loaded, load them now
 | |
| 			$this->getAttachmentsList();
 | |
| 			}
 | |
| 
 | |
| 		return $this->_some_modifiable;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * Returns the types of attachments
 | |
| 	 *
 | |
| 	 * @return 'file', 'url', 'both', or false (if no attachments)
 | |
| 	 */
 | |
| 	public function types()
 | |
| 	{
 | |
| 		// Make sure the attachments are loaded
 | |
| 		if ( $this->_list == null ) {
 | |
| 
 | |
| 			// See if we have already loaded the attachements list
 | |
| 			if ( $this->_num_attachments === 0 ) {
 | |
| 				return false;
 | |
| 				}
 | |
| 
 | |
| 			// Since the attachments have not been loaded, load them now
 | |
| 			$this->getAttachmentsList();
 | |
| 			}
 | |
| 
 | |
| 		// Scan the attachments
 | |
| 		$types = false;
 | |
| 		foreach ( $this->_list as $attachment ) {
 | |
| 			if ( $types ) {
 | |
| 				if ( $attachment->uri_type != $types ) {
 | |
| 					return 'both';
 | |
| 					}
 | |
| 				}
 | |
| 			else {
 | |
| 				$types = $attachment->uri_type;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 		return $types;
 | |
| 	}
 | |
| 
 | |
| }
 |