diff --git a/administrator/components/com_attachments/views/attachments/index.html b/administrator/components/com_attachments/views/attachments/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/administrator/components/com_attachments/views/attachments/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/administrator/components/com_attachments/views/attachments/tmpl/default.php b/administrator/components/com_attachments/views/attachments/tmpl/default.php new file mode 100644 index 00000000..32d82271 --- /dev/null +++ b/administrator/components/com_attachments/views/attachments/tmpl/default.php @@ -0,0 +1,43 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +?> +
+loadTemplate('filter');?> + + loadTemplate('head');?> + loadTemplate('body');?> + loadTemplate('foot');?> +
+
+ + + + + +
+
+ diff --git a/administrator/components/com_attachments/views/attachments/tmpl/default_body.php b/administrator/components/com_attachments/views/attachments/tmpl/default_body.php new file mode 100644 index 00000000..66f86b3c --- /dev/null +++ b/administrator/components/com_attachments/views/attachments/tmpl/default_body.php @@ -0,0 +1,164 @@ +params; +$secure = $params->get('secure',false); +$superimpose_link_icons = $params->get('superimpose_url_link_icons', true); +$icon_dir = $uri->root(true) . '/components/com_attachments/media/icons/'; + +// Loop through all the attachments +$k = 0; +$last_parent_id = null; +$last_parent_type = null; +$last_parent_entity = null; + + +for ($i=0, $n=count( $this->items ); $i < $n; $i++) +{ + $item = $this->items[$i]; + + if ( $item->uri_type == 'file' ) { + if ( $secure ) { + $url = JRoute::_("index.php?option=com_attachments&task=attachment.download&id=" . (int)$item->id); + } + else { + $url = $uri->root(true) . '/' . $item->url; + } + } + else { + $url = $item->url; + } + $checked = JHtml::_('grid.id', $i, $item->id ); + $published = JHtml::_('jgrid.published', $item->state, $i, 'attachments.' ); + $access = $this->level_name[$item->access]; + + $size_kb = (int)(10 * $item->file_size / 1024) / 10.0; + $link = JFilterOutput::ampReplace( 'index.php?option=com_attachments&task=attachment.edit&cid[]='. (int)$item->id ); + $view_parent_title = JText::_('ATTACH_VIEW_ARTICLE_TITLE'); + if ( JString::strlen($item->icon_filename) > 0 ) + $icon = $item->icon_filename; + else + $icon = 'generic.gif'; + $add_attachment_title = JText::_('ATTACH_ADD_ATTACHMENT_TITLE'); + $edit_attachment_title = JText::_('ATTACH_EDIT_THIS_ATTACHMENT_TITLE'); + $access_attachment_title = JText::_('ATTACH_ACCESS_THIS_ATTACHMENT_TITLE'); + + // Set up the create/modify dates + jimport( 'joomla.utilities.date' ); + $tz = new DateTimeZone( $user->getParam('timezone', $app->getCfg('offset')) ); + + $cdate = JFactory::getDate($item->created); + $cdate->setTimeZone($tz); + $created = $cdate->format("Y-m-d H:i", true); + + $mdate = JFactory::getDate($item->modified); + $mdate->setTimeZone($tz); + $modified = $mdate->format("Y-m-d H:i", true); + + $add_attachment_txt = JText::_('ATTACH_ADD_ATTACHMENT'); + if ( ($item->parent_id != $last_parent_id) || ($item->parent_type != $last_parent_type) + || ($item->parent_entity != $last_parent_entity) ) { + $parent_type = $item->parent_type; + if ( $item->parent_entity != 'default' ) { + $parent_type .= '.' . $item->parent_entity; + } + if ( ($item->parent_id == null) || !$item->parent_exists ) { + $artLine = ''; + $artLine .= ''.$item->parent_entity_type.': '.$item->parent_title.''; + $artLine .= ''; + } + else { + $addAttachLink = 'index.php?option=com_attachments&task=attachment.add&parent_id='. $item->parent_id . + '&parent_type=' . $parent_type . '&editor=add_to_parent'; + $addAttachLink = JFilterOutput::ampReplace($addAttachLink); + $artLine = "num_columns\">"; + $artLine .= "" . $item->parent_entity_type.": parent_url."\" target=\"_blank\">" . $item->parent_title . ""; + $artLine .= JFilterOutput::ampReplace('    '); + $artLine .= ""; + $artLine .= JHtml::image('com_attachments/add_attachment.gif', $add_attachment_txt, null, true); + $artLine .= " " . + "$add_attachment_txt"; + $artLine .= ""; + } + echo $artLine; + $k = 0; + } + $last_parent_id = $item->parent_id; + $last_parent_type = $item->parent_type; + $last_parent_entity = $item->parent_entity; + $download_verb = JText::_('ATTACH_DOWNLOAD_VERB'); + ?> + "> + + + + uri_type == 'url') && $superimpose_link_icons ) { + if ( $item->url_valid ) { + echo JHtml::image('com_attachments/file_icons/link_arrow.png', '', 'class="link_overlay"', true); + } + else { + echo JHtml::image('com_attachments/file_icons/link_broken.png', '', 'class="link_overlay"', true); + } + } + ?> uri_type == 'file' ) { + echo $item->filename; + } + else { + if ( $item->filename ) { + echo $item->filename; + } + else { + echo $item->url; + } + } + ?>   + + description)); ?> + + get('user_field_1_name', '') != '' ): ?> + user_field_1); ?> + + get('user_field_2_name', '') != '' ): ?> + user_field_2); ?> + + get('user_field_3_name', '') != '' ): ?> + user_field_3); ?> + + file_type; ?> + + creator_name; ?> + + + + download_count; ?> + + + lists; + +?> +
+ + + + + + +
+ + + + + + + +   +
+
diff --git a/administrator/components/com_attachments/views/attachments/tmpl/default_foot.php b/administrator/components/com_attachments/views/attachments/tmpl/default_foot.php new file mode 100644 index 00000000..74c9f9bc --- /dev/null +++ b/administrator/components/com_attachments/views/attachments/tmpl/default_foot.php @@ -0,0 +1,21 @@ + + +pagination->getListFooter(); ?> +
version); ?>
+ diff --git a/administrator/components/com_attachments/views/attachments/tmpl/default_head.php b/administrator/components/com_attachments/views/attachments/tmpl/default_head.php new file mode 100644 index 00000000..bfbc5528 --- /dev/null +++ b/administrator/components/com_attachments/views/attachments/tmpl/default_head.php @@ -0,0 +1,67 @@ +params; +$secure = $params->get('secure',false); +$lists = $this->lists; +$list_for_parents = $lists['list_for_parents']; + +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +?> + + + + + + + + + get('user_field_1_name')): ?> + get('user_field_1_name', ''), + 'a.user_field_1', $listDirn, $listOrder ) ?> + + get('user_field_2_name')): ?> + get('user_field_2_name', ''), + 'a.user_field_2', $listDirn, $listOrder ) ?> + + get('user_field_3_name')): ?> + get('user_field_3_name', ''), + 'a.user_field_3', $listDirn, $listOrder ) ?> + + + + + + + + + + + + diff --git a/administrator/components/com_attachments/views/attachments/tmpl/index.html b/administrator/components/com_attachments/views/attachments/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/administrator/components/com_attachments/views/attachments/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/administrator/components/com_attachments/views/attachments/view.html.php b/administrator/components/com_attachments/views/attachments/view.html.php new file mode 100644 index 00000000..33dc8e6e --- /dev/null +++ b/administrator/components/com_attachments/views/attachments/view.html.php @@ -0,0 +1,227 @@ +' . JText::_('ATTACH_WARNING_ATTACHMENTS_PLUGIN_FRAMEWORK_DISABLED') . ''; + return; + } + + $this->items = $this->get('Items'); + $this->state = $this->get('State'); + $this->pagination = $this->get('Pagination'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) { + JError::raiseError(500, implode("\n", $errors) . ' (ERR 175)'); + return false; + } + + // Get the params + jimport('joomla.application.component.helper'); + $params = JComponentHelper::getParams('com_attachments'); + $this->params = $params; + + // Get the access level names for the display + $db = JFactory::getDBO(); + $query = $db->getQuery(true); + $query->select('*')->from('#__viewlevels'); + $db->setQuery($query); + $levels = $db->loadObjectList(); + if ( $db->getErrorNum() ) { + $errmsg = $db->stderr() . ' (ERR 176)'; + JError::raiseError(500, $errmsg); + } + $level_name = Array(); + foreach ($levels as $level) { + // NOTE: We do not translate the access level title + $level_name[$level->id] = $level->title; + } + $this->level_name = $level_name; + + // Construct the special HTML lists + $lists = Array(); + + // Determine types of parents for which attachments should be displayed + $list_for_parents_default = 'ALL'; + $suppress_obsolete_attachments = $params->get('suppress_obsolete_attachments', false); + if ( $suppress_obsolete_attachments ) { + $list_for_parents_default = 'PUBLISHED'; + } + $app = JFactory::getApplication(); + $list_for_parents = + $app->getUserStateFromRequest('com_attachments.listAttachments.list_for_parents', + 'list_for_parents', $list_for_parents_default, 'word'); + $lists['list_for_parents'] = JString::strtolower($list_for_parents); + + // Add the drop-down menu to decide which attachments to show + $filter_parent_state = $this->state->get('filter.parent_state', 'ALL'); + $filter_parent_state_options = array(); + $filter_parent_state_options[] = JHtml::_('select.option', 'ALL', JText::_( 'ATTACH_ALL_PARENTS' ) ); + $filter_parent_state_options[] = JHtml::_('select.option', 'PUBLISHED', JText::_( 'ATTACH_PUBLISHED_PARENTS' ) ); + $filter_parent_state_options[] = JHtml::_('select.option', 'UNPUBLISHED', JText::_( 'ATTACH_UNPUBLISHED_PARENTS' ) ); + $filter_parent_state_options[] = JHtml::_('select.option', 'ARCHIVED', JText::_( 'ATTACH_ARCHIVED_PARENTS' ) ); + $filter_parent_state_options[] = JHtml::_('select.option', 'TRASHED', JText::_( 'ATTACH_TRASHED_PARENTS' ) ); + $filter_parent_state_options[] = JHtml::_('select.option', 'NONE', JText::_( 'ATTACH_NO_PARENTS' ) ); + $filter_parent_state_tooltip = JText::_('ATTACH_SHOW_FOR_PARENTS_TOOLTIP'); + $lists['filter_parent_state_menu'] = + JHtml::_('select.genericlist', $filter_parent_state_options, 'filter_parent_state', + 'class="inputbox" onChange="document.adminForm.submit();" title="' . + $filter_parent_state_tooltip . '"', 'value', 'text', $filter_parent_state); + $this->filter_parent_state = $filter_parent_state; + + // Add the drop-down menu to filter for types of entities + $filter_entity = $this->state->get('filter.entity', 'ALL'); + $filter_entity_options = array(); + $filter_entity_options[] = JHtml::_('select.option', 'ALL', JText::_( 'ATTACH_ALL_TYPES' ) ); + JPluginHelper::importPlugin('attachments'); + $apm = getAttachmentsPluginManager(); + $entity_info = $apm->getInstalledEntityInfo(); + foreach ($entity_info as $einfo) { + $filter_entity_options[] = JHtml::_('select.option', $einfo['id'], $einfo['name_plural']); + } + $filter_entity_tooltip = JText::_('ATTACH_FILTER_ENTITY_TOOLTIP'); + $lists['filter_entity_menu'] = + JHtml::_('select.genericlist', $filter_entity_options, 'filter_entity', + 'class="inputbox" onChange="this.form.submit();" ' . + 'title="'.$filter_entity_tooltip .'"', 'value', 'text', $filter_entity); + + $this->lists = $lists; + + // Figure out how many columns + $num_columns = 10; + if ( $params->get('user_field_1_name') ) { + $num_columns++; + } + if ( $params->get('user_field_2_name') ) { + $num_columns++; + } + if ( $params->get('user_field_3_name') ) { + $num_columns++; + } + if ( $params->get('secure',false) ) { + $num_columns++; + } + $this->num_columns = $num_columns; + + // get the version number + require_once(JPATH_SITE.'/components/com_attachments/defines.php'); + $this->version = AttachmentsDefines::$ATTACHMENTS_VERSION; + $this->project_url = AttachmentsDefines::$PROJECT_URL; + + // Add the style sheets + JHtml::stylesheet('com_attachments/attachments_admin.css', Array(), true); + $lang = JFactory::getLanguage(); + if ( $lang->isRTL() ) { + JHtml::stylesheet('com_attachments/attachments_admin_rtl.css', Array(), true); + } + + // Set the toolbar + $this->addToolBar(); + + // Display the attachments + parent::display($tpl); + } + + + /** + * Setting the toolbar + */ + protected function addToolBar() + { + require_once(JPATH_COMPONENT_ADMINISTRATOR.'/permissions.php'); + $canDo = AttachmentsPermissions::getActions(); + + $toolbar = JToolBar::getInstance('toolbar'); + + JToolBarHelper::title(JText::_('ATTACH_ATTACHMENTS'), 'attachments.png'); + + if ($canDo->get('core.create')) { + JToolBarHelper::addNew('attachment.add'); + } + + if ($canDo->get('core.edit') OR $canDo->get('core.edit.own') ) { + JToolBarHelper::editList('attachment.edit'); + } + + if ($canDo->get('core.edit.state') OR $canDo->get('attachments.edit.state.own')) { + JToolBarHelper::divider(); + JToolBarHelper::publishList('attachments.publish'); + JToolBarHelper::unpublishList('attachments.unpublish'); + } + + if ($canDo->get('core.delete') OR $canDo->get('attachments.delete.own')) { + JToolBarHelper::divider(); + JToolBarHelper::deleteList('', 'attachments.delete'); + } + + if ($canDo->get('core.admin')) { + JToolBarHelper::divider(); + JToolBarHelper::custom('params.edit', 'options', 'options', 'JTOOLBAR_OPTIONS', false); + + $icon_name = 'adminUtils'; + if (version_compare(JVERSION, '3.0', 'ge')) { + $icon_name = 'wrench'; + } + + // Add a button for extra admin commands + $toolbar->appendButton('Popup', $icon_name, 'ATTACH_UTILITIES', + 'index.php?option=com_attachments&task=adminUtils&tmpl=component', + 800, 500); + } + + JToolBarHelper::divider(); + + // Manually add a help button for the help view + $url = 'index.php?option=com_attachments&task=help&tmpl=component'; + $help = ' ' . JText::_('JTOOLBAR_HELP') . ' '; + if (version_compare(JVERSION, '3.0', 'ge')) + { + $link = ""; + } + else + { + $link = ' "; + $link .= " $help"; + } + $toolbar->appendButton('Custom', $link, 'toolbar-help'); + } + +} diff --git a/components/com_attachments/views/attachments/index.html b/components/com_attachments/views/attachments/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/components/com_attachments/views/attachments/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/components/com_attachments/views/attachments/metadata.xml b/components/com_attachments/views/attachments/metadata.xml new file mode 100644 index 00000000..a46b551b --- /dev/null +++ b/components/com_attachments/views/attachments/metadata.xml @@ -0,0 +1,5 @@ + + + + diff --git a/components/com_attachments/views/attachments/tmpl/default.php b/components/com_attachments/views/attachments/tmpl/default.php new file mode 100644 index 00000000..174e7700 --- /dev/null +++ b/components/com_attachments/views/attachments/tmpl/default.php @@ -0,0 +1,344 @@ +get('username') <> ''; + +$app = JFactory::getApplication(); +$uri = JFactory::getURI(); + +// Set a few variables for convenience +$attachments = $this->list; +$parent_id = $this->parent_id; +$parent_type = $this->parent_type; +$parent_entity = $this->parent_entity; + +$base_url = $this->base_url; + +$format = JRequest::getWord('format', ''); + +$html = ''; + +if ( $format != 'raw' ) { + + // If any attachments are modifiable, add necessary Javascript for iframe + if ( $this->some_attachments_modifiable ) { + AttachmentsJavascript::setupModalJavascript(); + } + + // Construct the empty div for the attachments + if ( $parent_id === null ) { + // If there is no parent_id, the parent is being created, use the username instead + $pid = $user->get('username'); + } + else { + $pid = $parent_id; + } + $div_id = 'attachmentsList' . '_' . $parent_type . '_' . $parent_entity . '_' . (string)$pid; + $html .= "\n
style\" id=\"$div_id\">\n"; + } + +$html .= "\n"; +$html .= "\n"; + +// Add the column titles, if requested +if ( $this->show_column_titles ) { + $html .= "\n"; + $html .= ""; + if ( $this->show_description ) { + $html .= ""; + } + if ( $this->show_user_field_1 ) { + $html .= ""; + } + if ( $this->show_user_field_2 ) { + $html .= ""; + } + if ( $this->show_user_field_3 ) { + $html .= ""; + } + if ( $this->show_creator_name ) { + $html .= ""; + } + if ( $this->show_file_size ) { + $html .= ""; + } + if ( $this->secure && $this->show_downloads ) { + $html .= ""; + } + if ( $this->show_created_date ) { + $html .= ""; + } + if ( $this->show_modified_date ) { + $html .= ""; + } + if ( $this->some_attachments_modifiable && $this->allow_edit ) { + $html .= ""; + } + $html .= "\n\n"; + } + +$html .= "\n"; + +// Construct the lines for the attachments +$row_num = 0; +for ($i=0, $n=count($attachments); $i < $n; $i++) { + $attachment = $attachments[$i]; + + $row_num++; + if ( $row_num & 1 == 1) { + $row_class = 'odd'; + } + else { + $row_class = 'even'; + } + + if ($attachment->state != 1) { + $row_class = 'unpublished'; + } + + $html .= ''; + + // Construct some display items + if ( JString::strlen($attachment->icon_filename) > 0 ) + $icon = $attachment->icon_filename; + else + $icon = 'generic.gif'; + + if ( $this->show_file_size) { + $file_size = (int)( $attachment->file_size / 1024.0 ); + if ( $file_size == 0 ) { + // For files less than 1kB, show the fractional amount (in 1/10 kB) + $file_size = ( (int)( 10.0 * $attachment->file_size / 1024.0 ) / 10.0 ); + } + } + + if ( $this->show_created_date OR $this->show_modified_date ) { + jimport( 'joomla.utilities.date' ); + $tz = new DateTimeZone( $user->getParam('timezone', $app->getCfg('offset')) ); + } + + if ( $this->show_created_date ) { + $date = JFactory::getDate($attachment->created); + $date->setTimezone($tz); + $created = $date->format($this->date_format, true); + } + + if ( $this->show_modified_date ) { + $date = JFactory::getDate($attachment->modified); + $date->setTimezone($tz); + $last_modified = $date->format($this->date_format, true); + } + + // Add the filename + $target = ''; + if ( $this->file_link_open_mode == 'new_window') + $target = ' target="_blank"'; + $html .= '"; + + // Add description (maybe) + if ( $this->show_description ) { + $description = htmlspecialchars(stripslashes($attachment->description)); + if ( JString::strlen($description) == 0) + $description = ' '; + if ( $this->show_column_titles ) + $html .= ""; + else + $html .= ""; + } + + // Show the USER DEFINED FIELDs (maybe) + if ( $this->show_user_field_1 ) { + $user_field = stripslashes($attachment->user_field_1); + if ( JString::strlen($user_field) == 0 ) + $user_field = ' '; + if ( $this->show_column_titles ) + $html .= ""; + else + $html .= ""; + } + if ( $this->show_user_field_2 ) { + $user_field = stripslashes($attachment->user_field_2); + if ( JString::strlen($user_field) == 0 ) + $user_field = ' '; + if ( $this->show_column_titles ) + $html .= ""; + else + $html .= ""; + } + if ( $this->show_user_field_3 ) { + $user_field = stripslashes($attachment->user_field_3); + if ( JString::strlen($user_field) == 0 ) + $user_field = ' '; + if ( $this->show_column_titles ) + $html .= ""; + else + $html .= ""; + } + + // Add the creator's username (if requested) + if ( $this->show_creator_name ) { + $html .= ""; + } + + // Add file size (maybe) + if ( $this->show_file_size ) { + $file_size_str = JText::sprintf('ATTACH_S_KB', $file_size); + if ( $file_size_str == 'ATTACH_S_KB' ) { + // Work around until all translations are updated ??? + $file_size_str = $file_size . ' kB'; + } + $html .= ''; + } + + // Show number of downloads (maybe) + if ( $this->secure && $this->show_downloads ) { + $num_downloads = (int)$attachment->download_count; + $label = ''; + if ( ! $this->show_column_titles ) { + if ( $num_downloads == 1 ) + $label = ' ' . JText::_('ATTACH_DOWNLOAD_NOUN'); + else + $label = ' ' . JText::_('ATTACH_DOWNLOADS'); + } + $html .= ''; + } + + // Add the created and modification date (maybe) + if ( $this->show_created_date ) { + $html .= ""; + } + if ( $this->show_modified_date ) { + $html .= ""; + } + + $update_link = ''; + $delete_link = ''; + + $a_class = 'modal-button'; + if ( $app->isAdmin() ) { + $a_class = 'modal'; + } + + // Add the link to edit the attachment, if requested + if ( $this->some_attachments_modifiable && $attachment->user_may_edit && $this->allow_edit ) { + + // Create the edit link + $update_url = str_replace('%d', (string)$attachment->id, $this->update_url); + $tooltip = JText::_('ATTACH_UPDATE_THIS_FILE') . ' (' . $actual_filename . ')'; + $update_link = ""; + $update_link .= JHtml::image('com_attachments/pencil.gif', $tooltip, null, true); + $update_link .= ""; + } + + // Add the link to delete the attachment, if requested + if ( $this->some_attachments_modifiable && $attachment->user_may_delete && $this->allow_edit ) { + + // Create the delete link + $delete_url = str_replace('%d', (string)$attachment->id, $this->delete_url); + $tooltip = JText::_('ATTACH_DELETE_THIS_FILE') . ' (' . $actual_filename . ')'; + $delete_link = ""; + $delete_link .= JHtml::image('com_attachments/delete.gif', $tooltip, null, true); + $delete_link .= ""; + } + + if ( $this->some_attachments_modifiable && $this->allow_edit ) { + $html .= ""; + } + + $html .= "\n"; + } + +// Close the HTML +$html .= "
{$this->title}
" . $this->file_url_title . "" . JText::_('ATTACH_DESCRIPTION') . "" . $this->user_field_1_name . "" . $this->user_field_2_name . "" . $this->user_field_3_name . "" . JText::_('ATTACH_CREATOR') . "" . JText::_('ATTACH_FILE_SIZE') . "" . JText::_('ATTACH_DOWNLOADS') . "" . JText::_('ATTACH_CREATED') . "" . JText::_('ATTACH_LAST_MODIFIED') . " 
'; + if ( JString::strlen($attachment->display_name) == 0 ) + $filename = $attachment->filename; + else + $filename = htmlspecialchars(stripslashes($attachment->display_name)); + $actual_filename = $attachment->filename; + // Uncomment the following two lines to replace '.pdf' with its HTML-encoded equivalent + // $actual_filename = JString::str_ireplace('.pdf', '.pdf', $actual_filename); + // $filename = JString::str_ireplace('.pdf', '.pdf', $filename); + + if ( $this->show_file_links ) { + if ( $attachment->uri_type == 'file' ) { + // Handle file attachments + if ( $this->secure ) { + $url = JRoute::_($base_url . "index.php?option=com_attachments&task=download&id=" . (int)$attachment->id); + } + else { + $url = $base_url . $attachment->url; + if (strtoupper(substr(PHP_OS,0,3) == 'WIN')) { + $url = utf8_encode($url); + } + } + $tooltip = JText::sprintf('ATTACH_DOWNLOAD_THIS_FILE_S', $actual_filename); + } + else { + // Handle URL "attachments" + if ( $this->secure ) { + $url = JRoute::_($base_url . "index.php?option=com_attachments&task=download&id=" . (int)$attachment->id); + $tooltip = JText::sprintf('ATTACH_ACCESS_THIS_URL_S', $filename); + } + else { + // Handle the link url if not logged in but link displayed for guests + $url = ''; + if ( !$logged_in AND ($attachment->access != '1')) { + $guest_levels = $this->params->get('show_guest_access_levels', Array('1')); + if ( in_array($attachment->access, $guest_levels) ) { + $app = JFactory::getApplication(); + $return = $app->getUserState('com_attachments.current_url', ''); + $url = JRoute::_($base_url . 'index.php?option=com_attachments&task=requestLogin' . $return); + $target = ''; + } + } + if ( $url == '' ) { + $url = $attachment->url; + } + $tooltip = JText::sprintf('ATTACH_ACCESS_THIS_URL_S', $attachment->url); + } + } + $html .= ""; + $html .= JHtml::image('com_attachments/file_icons/'.$icon, $tooltip, null, true); + if ( ($attachment->uri_type == 'url') && $this->superimpose_link_icons ) { + if ( $attachment->url_valid ) { + $html .= JHtml::image('com_attachments/file_icons/link_arrow.png', '', 'class="link_overlay"', true); + } + else { + $html .= JHtml::image('com_attachments/file_icons/link_broken.png', '', 'class="link_overlay"', true); + } + } + $html .= ""; + $html .= "$filename"; + } + else { + $tooltip = JText::sprintf('ATTACH_DOWNLOAD_THIS_FILE_S', $actual_filename); + $html .= JHtml::image('com_attachments/file_icons/'.$icon, $tooltip, null, true); + $html .= ' ' . $filename; + } + $html .= "$description[$description]" . $user_field . "[" . $user_field . "]" . $user_field . "[" . $user_field . "]" . $user_field . "[" . $user_field . "]{$attachment->creator_name}' . $file_size_str . ''. $num_downloads.$label.'$created$last_modified$update_link $delete_link
\n"; + +if ( $format != 'raw' ) { + $html .= "
\n"; + } + +echo $html; diff --git a/components/com_attachments/views/attachments/tmpl/default.xml b/components/com_attachments/views/attachments/tmpl/default.xml new file mode 100644 index 00000000..9c45fdbc --- /dev/null +++ b/components/com_attachments/views/attachments/tmpl/default.xml @@ -0,0 +1,5 @@ + + + + diff --git a/components/com_attachments/views/attachments/tmpl/index.html b/components/com_attachments/views/attachments/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/components/com_attachments/views/attachments/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/components/com_attachments/views/attachments/view.html.php b/components/com_attachments/views/attachments/view.html.php new file mode 100644 index 00000000..c0f86a60 --- /dev/null +++ b/components/com_attachments/views/attachments/view.html.php @@ -0,0 +1,230 @@ +setMimeEncoding('text/plain'); + } + + // Add javascript + $uri = JFactory::getURI(); + AttachmentsJavascript::setupJavascript(); + + // Get the model + $model = $this->getModel('Attachments'); + if ( !$model ) { + $errmsg = JText::_('ATTACH_ERROR_UNABLE_TO_FIND_MODEL') . ' (ERR 63)'; + JError::raiseError( 500, $errmsg); + } + + // See if there are any attachments + $list = $model->getAttachmentsList(); + if ( ! $list ) { + return null; + } + + // if we have attachments, add the stylesheets for the attachments list + JHtml::stylesheet('com_attachments/attachments_list.css', array(), true); + $lang = JFactory::getLanguage(); + if ( $lang->isRTL() ) { + JHtml::stylesheet('com_attachments/attachments_list_rtl.css', array(), true); + } + + // Add the default path + $this->addTemplatePath(JPATH_SITE.'/components/com_attachments/views/attachments/tmpl'); + + // Set up the correct path for template overloads + // (Do this after previous addTemplatePath so that template overrides actually override) + $app = JFactory::getApplication(); + $templateDir = JPATH_SITE.'/templates/'.$app->getTemplate().'/html/com_attachments/attachments'; + $this->addTemplatePath($templateDir); + + // Load the language files from the attachments plugin + $lang = JFactory::getLanguage(); + $lang->load('plg_content_attachments', JPATH_SITE.'/plugins/content/attachments'); + + // Get the component parameters + $params = JComponentHelper::getParams('com_attachments'); + + // See whether the user-defined fields should be shown + $from = JRequest::getWord('from', 'closeme'); + $layout = JRequest::getWord('layout'); + $tmpl = JRequest::getWord('tmpl'); + $task = JRequest::getWord('task'); + $show_hidden_user_fields = false; + if ( $app->isAdmin() || ($from == 'editor') || ($layout == 'edit') || ($tmpl == 'component') ) { + $show_hidden_user_fields = true; + } + if ( $task == 'attachmentsList' ) { + // Always hide the hidden user fields on Ajax requests + $show_hidden_user_fields = false; + } + + // User field 1 + $show_user_field_1 = false; + $user_field_1_name = $params->get('user_field_1_name'); + if ( $user_field_1_name ) { + if ( $show_hidden_user_fields || ($user_field_1_name[JString::strlen($user_field_1_name)-1] != '*') ) { + $show_user_field_1 = true; + $this->user_field_1_name = $user_field_1_name; + } + } + $this->show_user_field_1 = $show_user_field_1; + + // User field 2 + $show_user_field_2 = false; + $user_field_2_name = $params->get('user_field_2_name'); + if ( $user_field_2_name ) { + if ( $show_hidden_user_fields || ($user_field_2_name[JString::strlen($user_field_2_name)-1] != '*') ) { + $show_user_field_2 = true; + $this->user_field_2_name = $user_field_2_name; + } + } + $this->show_user_field_2 = $show_user_field_2; + + // User field 3 + $show_user_field_3 = false; + $user_field_3_name = $params->get('user_field_3_name'); + if ( $user_field_3_name ) { + if ( $show_hidden_user_fields || ($user_field_3_name[JString::strlen($user_field_3_name)-1] != '*') ) { + $show_user_field_3 = true; + $this->user_field_3_name = $user_field_3_name; + } + } + $this->show_user_field_3 = $show_user_field_3; + + // Set up for the template + $parent_id = $model->getParentId(); + $parent_type = $model->getParentType(); + $parent_entity = JString::strtolower($model->getParentEntity()); + // ?? fix this! + if ( ($parent_type == 'com_content') && ($parent_entity == 'default') ) { + $parent_entity = 'article'; + } + $this->parent_id = $parent_id; + $this->parent_type = $parent_type; + $this->parent_entity = $parent_entity; + $this->parent_title = $model->getParentTitle(); + $this->parent_entity_name = $model->getParentEntityName(); + + $this->some_attachments_visible = $model->someVisible(); + $this->some_attachments_modifiable = $model->someModifiable(); + + $this->from = $from; + + $this->list = $list; + + $this->secure = $params->get('secure', false); + + $this->params = $params; + + // Get the display options + $this->superimpose_link_icons = $params->get('superimpose_url_link_icons', true); + $this->style = $params->get('attachments_table_style', 'attachmentsList'); + $this->show_column_titles = $params->get('show_column_titles', false); + $this->show_description = $params->get('show_description', true); + $this->show_creator_name = $params->get('show_creator_name', false); + $this->show_file_size = $params->get('show_file_size', true); + $this->show_downloads = $params->get('show_downloads', false); + $this->show_created_date = $params->get('show_created_date', false); + $this->show_modified_date = $params->get('show_modified_date', false); + $this->file_link_open_mode = $params->get('file_link_open_mode', 'in_same_window'); + + // Set up the file/url titleshow_mod_date + if ( $this->show_column_titles ) { + switch ( $model->types() ) { + case 'file': + $this->file_url_title = JText::_('ATTACH_FILE'); + break; + case 'url': + $this->file_url_title = JText::_('ATTACH_URL'); + break; + default: + $this->file_url_title = JText::_('ATTACH_FILE_URL'); + } + } + + if ( $this->show_created_date OR $this->show_modified_date ) { + $this->date_format = $params->get('date_format', '%Y-%m-%d %I:%M%P'); + } + + // Get the attachments list title + $title = $this->title; + if ( !$title || (JString::strlen($title) == 0) ) { + $title = 'ATTACH_ATTACHMENTS_TITLE'; + } + $parent = $model->getParentClass(); + $title = $parent->attachmentsListTitle($title, $parent_id, $parent_entity); + $this->title = $title; // Note: assume it is translated + + // Construct the path for the icons + $uri = JFactory::getURI(); + $base_url = $uri->root(false); + $this->base_url = $base_url; + $this->icon_url_base = $base_url . 'components/com_attachments/media/icons/'; + + // Get the output of the template + $result = $this->loadTemplate($tpl); + if (JError::isError($result)) { + return $result; + } + + return true; + } + + /** + * Get the output + * + * @return string the output + */ + public function getOutput() + { + return $this->_output; + } + +} diff --git a/components/com_attachments/views/attachments/view.raw.php b/components/com_attachments/views/attachments/view.raw.php new file mode 100644 index 00000000..c336cdc9 --- /dev/null +++ b/components/com_attachments/views/attachments/view.raw.php @@ -0,0 +1,18 @@ + + * @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 plugin class */ +if (!JPluginHelper::importPlugin('attachments', 'attachments_plugin_framework')) +{ + // Fail gracefully if the Attachments plugin framework plugin is disabled + return; +} + + +/** + * The class for the Attachments plugin for regular Joomla! content (articles, categories) + * + * @package Attachments + * @since 3.0 + */ +class AttachmentsPlugin_Com_Content extends AttachmentsPlugin +{ + /** + * 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); + + // Configure the plugin + $this->_name = 'attachments_for_content'; + + // Set basic attachments defaults + $this->parent_type = 'com_content'; + $this->default_entity = 'article'; + + // Add the information about the default entity (article) + $this->entities[] = 'article'; + $this->entity_name['article'] = 'article'; + $this->entity_name['default'] = 'article'; + $this->entity_table['article'] = 'content'; + $this->entity_id_field['article'] = 'id'; + $this->entity_title_field['article'] = 'title'; + + // Add information about the category description entity + $this->entities[] = 'category'; + $this->entity_name['category'] = 'category'; + $this->entity_table['category'] = 'categories'; + $this->entity_id_field['category'] = 'id'; + $this->entity_title_field['category'] = 'title'; + + // Always load the language + $this->loadLanguage(); + } + + /** + * 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. + * + * @param &object &$parent The object for the parent (row) that onPrepareContent gets + * + * @return the correct parent entity (eg, 'article', 'category') + */ + public function determineParentEntity(&$parent) + { + $view = JRequest::getCmd('view'); + + // Handle category calls + if (($view == 'category') && (get_class($parent) == 'JTableContent')) + { + return 'category'; + } + + // Handle everything else (articles) + // (apparently this is called before parents are displayed so ignore those calls) + if (isset($parent->id)) + { + return 'default'; + } + + return false; + } + + /** + * 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) + { + $view = JRequest::getCmd('view'); + $layout = JRequest::getCmd('layout'); + + $text_field_name = parent::getTextFieldName($row, $parent_entity); + + // In the case of a blog, we know what text_field_name should be + if (isset($row->introtext) AND ($layout == 'blog')) + { + $text_field_name = 'introtext'; + } + + // Featured also uses 'introtext' + if (isset($row->introtext) AND ($view == 'featured')) + { + $text_field_name = 'introtext'; + } + + // Check for non-menu category view + if (isset($row->introtext) AND ($view == 'category') AND + (($parent_entity == 'default') OR ($parent_entity == 'article'))) + { + $text_field_name = 'introtext'; + } + + if (version_compare(JVERSION, '3.4.0', 'ge') AND + ($view == 'category') AND ($layout == 'blog') AND ($parent_entity == 'article')) + { + $text_field_name = 'text'; + } + + return $text_field_name; + } + + /** + * 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') + { + $parent_entity = $this->getCanonicalEntityId($parent_entity); + + switch ($parent_entity) + { + + case 'category': + return parent::getSelectEntityURL($parent_entity); + break; + + default: + return "index.php?option=com_content&view=articles&layout=modal&tmpl=component&function=jSelectParentArticle"; + } + } + + /** + * 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 = '') + { + $db = JFactory::getDBO(); + + $parent_entity = $this->getCanonicalEntityId($parent_entity); + $parent_entity_name = JText::_('ATTACH_' . $parent_entity); + + // Note that article is handled separately + if (JString::strtolower($parent_entity) != 'category') + { + $errmsg = JText::sprintf('ATTACH_ERROR_GETTING_LIST_OF_ENTITY_S_ITEMS', $parent_entity_name) . ' (ERR 400)'; + JError::raiseError(500, $errmsg); + } + + $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 + $query = $db->getQuery(true); + $query->select('*')->from('#__categories'); + + // Filter + if ($filter) + { + $filter = $db->quote('%' . $db->escape($filter, true) . '%', false); + $query->where('title LIKE ' . $filter); + } + $query->where('extension=' . $db->quote('com_content')); + + // NOTE: Ignore any requested order since only ordering by lft makes the hierarchy work + $query->order('lft'); + + // Do the query + $db->setQuery($query); + $items = $db->loadObjectList(); + if ($db->getErrorNum()) + { + $errmsg = JText::sprintf('ATTACH_ERROR_GETTING_LIST_OF_ENTITY_S_ITEMS', $parent_entity_name) . ' (ERR 401)
' . $db->stderr(); + JError::raiseError(500, $errmsg); + } + + if ($items == null) + { + return null; + } + + // Set up the hierarchy indenting + foreach ($items as &$item) + { + $repeat = ($item->level - 1 >= 0) ? $item->level - 1 : 0; + $item->title = str_repeat('- ', $repeat) . $item->title; + } + + return $items; + } + + /** + * 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') + { + $parent_entity = $this->getCanonicalEntityId($parent_entity); + + $db = JFactory::getDBO(); + $query = $db->getQuery(true); + + $result = 0; + + // Return the right thing for each entity + switch ($parent_entity) + { + + case 'category': + $query->select('created_user_id')->from('#__categories')->where('id = ' . (int) $parent_id); + $db->setQuery($query, 0, 1); + $result = $db->loadResult(); + if ($db->getErrorNum()) + { + $errmsg = JText::_('ATTACH_ERROR_CHECKING_CATEGORY_PERMISSIONS') . ' (ERR 402)'; + JError::raiseError(500, $errmsg); + } + break; + + default: // Article + $query->select('created_by')->from('#__content')->where('id = ' . (int) $parent_id); + $db->setQuery($query, 0, 1); + $result = $db->loadResult(); + if ($db->getErrorNum()) + { + $errmsg = JText::_('ATTACH_ERROR_CHECKING_ARTICLE_PERMISSIONS') . ' (ERR 403)'; + JError::raiseError(500, $errmsg); + } + } + + if (is_numeric($result)) + { + return (int) $result; + } + + return 0; + } + + /** + * Get a URL to view the content article + * + * @param int $parent_id the ID for this parent object + * @param string $parent_entity the type of parent element/entity + * + * @return a URL to view the entity (non-SEF form) + */ + public function getEntityViewURL($parent_id, $parent_entity = 'default') + { + $uri = JFactory::getURI(); + + $base_url = $uri->root(true) . '/'; + + // Return the right thing for each entity + switch ($parent_entity) + { + + case 'category': + return $base_url . 'index.php?option=com_content&view=category&id=' . $parent_id; + break; + + default: + return $base_url . 'index.php?option=com_content&view=article&id=' . $parent_id; + } + } + + /** + * 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(); + + $parent_entity = $this->getCanonicalEntityId($parent_entity); + + // Determine the task + if ($app->isAdmin()) + { + $task = 'attachment.add'; + } + else + { + $task = 'upload'; + } + + // Handle article creation + $url = "index.php?option=com_attachments&task=$task"; + if ($parent_id == null) + { + $url .= "&parent_id=$parent_id,new"; + } + else + { + $url .= "&parent_id=$parent_id"; + } + + // Build the right URL for each entity + switch ($parent_entity) + { + + case 'category': + $url .= "&parent_type=com_content.$parent_entity&from=$from"; + break; + + default: + $url .= "&parent_type=com_content.article&from=$from"; + } + + return $url; + } + + /** + * Check to see if a custom title applies to this parent + * + * Note: this function assumes that the parent_id's match + * + * @param string $parent_entity 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) + { + if ((($parent_entity == 'default') || ($parent_entity == 'article')) + && (($rtitle_parent_entity == 'default') || ($rtitle_parent_entity == 'article'))) + { + return true; + } + + if (($parent_entity == 'category') && ($parent_entity == $rtitle_parent_entity)) + { + return true; + } + + return false; + } + + /** + * 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) + { + if ($attachment->parent_id != 0) { + return false; + } + + if ($attachment->parent_entity == 'article') { + // Seems to be true for articles + return true; + } + + if ($attachment->parent_entity == 'category') { + // Assume this is true for category (but not sure) + return true; + } + + return false; + } + + /** + * Check to see if the parent is published + * + * @param int $parent_id is 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') + { + $db = JFactory::getDBO(); + + $published = false; + + $parent_entity = $this->getCanonicalEntityId($parent_entity); + $parent_entity_name = JText::_('ATTACH_' . $parent_entity); + + // Return the right thing for each entity + switch ($parent_entity) + { + + case 'category': + $entity_table = $this->entity_table[$parent_entity]; + $query = $db->getQuery(true); + $query->select('published')->from("#__$entity_table")->where('id = ' . (int) $parent_id); + $db->setQuery($query, 0, 1); + $obj = $db->loadObject(); + if ($db->getErrorNum()) + { + $errmsg = JText::sprintf('ATTACH_ERROR_INVALID_PARENT_S_ID_N', $parent_entity_name, $parent_id) . ' (ERR 404)'; + JError::raiseError(500, $errmsg); + } + if (is_object($obj)) + { + $published = $obj->published == 1; + } + else + { + $published = false; + } + break; + + default: + + // Check for articles + $query = $db->getQuery(true); + $query->select('state, publish_up, publish_down')->from('#__content'); + $query->where('id = ' . (int) $parent_id); + $db->setQuery($query, 0, 1); + $article = $db->loadObject(); + if ($db->getErrorNum()) + { + $errmsg = JText::sprintf('ATTACH_ERROR_INVALID_PARENT_S_ID_N', $parent_entity_name, $parent_id) . ' (ERR 405)'; + JError::raiseError(500, $errmsg); + } + else + { + $now = JFactory::getDate()->toUnix(); + $nullDate = JFactory::getDate($db->getNullDate())->toUnix(); + + if ($article) + { + $publish_up = JFactory::getDate($article->publish_up)->toUnix(); + $publish_down = JFactory::getDate($article->publish_down)->toUnix(); + + $published = (($article->state == 1) && ($now >= $publish_up) && (($publish_down == $nullDate) || ($now <= $publish_down))); + } + else + { + $published = false; + } + } + } + + return $published; + } + + /** + * Check to see if the parent is archived + * + * @param int $parent_id is 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') + { + $archived = false; + + $parent_entity = $this->getCanonicalEntityId($parent_entity); + + // Return the right thing for each entity + switch ($parent_entity) + { + + case 'category': + // You apparently cannot archive categories + break; + + default: + // Articles + $db = JFactory::getDBO(); + $query = $db->getQuery(true); + $query->select('state')->from('#__content')->where(' id = ' . (int) $parent_id); + $db->setQuery($query, 0, 1); + $article = $db->loadObject(); + if ($db->getErrorNum()) + { + $parent_entity_name = JText::_('ATTACH_' . $parent_entity); + $errmsg = JText::sprintf('ATTACH_ERROR_INVALID_PARENT_S_ID_N', $parent_entity_name, $parent_id) . ' (ERR 406)'; + JError::raiseError(500, $errmsg); + } + else + { + if ($article) + { + $archived = $article->state == -1; + } + else + { + $archived = false; + } + } + } + + return $archived; + } + + /** + * 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') + * + * @return an array of where clauses + */ + public function getParentPublishedFilter($parent_state, $filter_entity) + { + // If we want all attachments, do no filtering + if ($parent_state == 'ALL') + { + return array(); + } + + $db = JFactory::getDBO(); + + $where = Array(); + + $filter_entity = JString::strtoupper($filter_entity); + + // NOTE: These WHERE clauses will be combined by OR + + if ($parent_state == 'PUBLISHED') + { + + if (($filter_entity == 'ALL') || ($filter_entity == 'ARTICLE')) + { + $now = JFactory::getDate()->toSql(); + $nullDate = $db->getNullDate(); + $where[] = "EXISTS (SELECT * FROM #__content AS c1 " . + "WHERE (a.parent_entity = 'article' AND c1.id = a.parent_id AND c1.state=1 AND " . + '(c1.publish_up = ' . $db->quote($nullDate) . ' OR c1.publish_up <= ' . $db->quote($now) . ') AND ' . + '(c1.publish_down = ' . $db->quote($nullDate) . ' OR c1.publish_down >= ' . $db->quote($now) . ')))'; + } + + if (($filter_entity == 'ALL') || ($filter_entity == 'CATEGORY')) + { + $where[] = "EXISTS (SELECT * FROM #__categories AS c2 " . + "WHERE (a.parent_entity = 'category' AND c2.id = a.parent_id AND c2.published=1))"; + } + } + elseif ($parent_state == 'UNPUBLISHED') + { + // These WHERE clauses will be combined by OR + if (($filter_entity == 'ALL') || ($filter_entity == 'ARTICLE')) + { + $where[] = "EXISTS (SELECT * FROM #__content AS c1 " . + "WHERE (a.parent_entity = 'article' AND c1.id = a.parent_id AND c1.state=0))"; + $where[] = "(a.parent_entity = 'article' AND NOT EXISTS (select * from #__content as c1 where c1.id = a.parent_id))"; + + // ??? Add clauses here to get articles that are unpublished because of publish_up/publish_down + } + + if (($filter_entity == 'ALL') || ($filter_entity == 'CATEGORY')) + { + $where[] = "EXISTS (SELECT * FROM #__categories AS c2 " . + "WHERE (a.parent_entity = 'category' AND c2.id = a.parent_id AND c2.published=0))"; + $where[] = "(a.parent_entity = 'category' AND NOT EXISTS (select * from #__categories as c1 where c1.id = a.parent_id))"; + } + } + elseif ($parent_state == 'ARCHIVED') + { + // These WHERE clauses will be combined by OR + if (($filter_entity == 'ALL') || ($filter_entity == 'ARTICLE')) + { + $where[] = "EXISTS (SELECT * FROM #__content AS c1 " . + "WHERE (a.parent_entity = 'article' AND c1.id = a.parent_id AND c1.state=2))"; + } + + if (($filter_entity == 'ALL') || ($filter_entity == 'CATEGORY')) + { + $where[] = "EXISTS (SELECT * FROM #__categories AS c2 " . + "WHERE (a.parent_entity = 'category' AND c2.id = a.parent_id AND c2.published=2))"; + } + } + elseif ($parent_state == 'TRASHED') + { + // These WHERE clauses will be combined by OR + if (($filter_entity == 'ALL') || ($filter_entity == 'ARTICLE')) + { + $where[] = "EXISTS (SELECT * FROM #__content AS c1 " . + "WHERE (a.parent_entity = 'article' AND c1.id = a.parent_id AND c1.state=-2))"; + } + + if (($filter_entity == 'ALL') || ($filter_entity == 'CATEGORY')) + { + $where[] = "EXISTS (SELECT * FROM #__categories AS c2 " . + "WHERE (a.parent_entity = 'category' AND c2.id = a.parent_id AND c2.published=-2))"; + } + } + elseif ($parent_state == 'NONE') + { + // NOTE: The 'NONE' clauses will be combined with AND (with other tests for a.parent_id) + $where[] = "(NOT EXISTS( SELECT * FROM #__content as c1 " . + "WHERE a.parent_entity = 'article' AND c1.id = a.parent_id ))"; + + $where[] = "(NOT EXISTS( SELECT * FROM #__categories as c2 " . + "WHERE a.parent_entity = 'category' AND c2.id = a.parent_id ))"; + } + else + { + $errmsg = JText::sprintf('ATTACH_ERROR_UNRECOGNIZED_PARENT_STATE_S', $parent_state) . ' (ERR 407)'; + JError::raiseError(500, $errmsg); + } + + return $where; + } + + /** + * May the parent be viewed by the user? + * + * @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) + { + $parent_entity = $this->getCanonicalEntityId($parent_entity); + + // Return the right thing for each entity + $table = null; + switch ($parent_entity) + { + + case 'category': + $table = 'categories'; + break; + + default: + // Article + $table = 'content'; + break; + } + + // Get the user's permitted access levels + $user = JFactory::getUser($user_id); + $user_levels = array_unique($user->getAuthorisedViewLevels()); + + // See if the parent's access level is permitted for the user + $db = JFactory::getDBO(); + $query = $db->getQuery(true); + $query->select('id')->from("#__$table"); + $query->where('id = ' . (int) $parent_id . ' AND access in (' . implode(',', $user_levels) . ')'); + $db->setQuery($query, 0, 1); + $obj = $db->loadObject(); + if ($db->getErrorNum()) + { + $parent_entity_name = JText::_('ATTACH_' . $parent_entity); + $errmsg = JText::sprintf('ATTACH_ERROR_INVALID_PARENT_S_ID_N', $parent_entity_name, $parent_id) . ' (ERR 408)'; + JError::raiseError(500, $errmsg); + } + + return !empty($obj); + } + + /** 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 + * + * @return true if the attachments should be hidden for this parent + */ + public function attachmentsHiddenForParent(&$parent, $parent_id, $parent_entity) + { + // Check for generic options + if (parent::attachmentsHiddenForParent($parent, $parent_id, $parent_entity)) + { + return true; + } + $pclass = get_class($parent); + + $parent_entity = $this->getCanonicalEntityId($parent_entity); + $parent_entity_name = JText::_('ATTACH_' . $parent_entity); + + // Make sure we have a valid parent ID + if (!$parent_id && ($parent_entity == 'category')) + { + $parent_id = JRequest::getInt('id'); + } + if ($parent_id !== 0) + { + // Note: parent_id of 0 may be allowed for categories, so don't abort + if (($parent_id == null) || ($parent_id == '') || !is_numeric($parent_id)) + { + $errmsg = JText::sprintf('ATTACH_ERROR_BAD_ENTITY_S_ID', $parent_entity_name) . ' (ERR 409)'; + JError::raiseError(500, $errmsg); + } + } + + // Check to see if it should be hidden with readmore + $aparams = $this->attachmentsParams(); + $hide_with_readmore = $aparams->get('hide_with_readmore', false); + if ($hide_with_readmore && isset($parent->readmore) && $parent->readmore) + { + return true; + } + + // Get the options + $all_but_article_views = $aparams->get('hide_except_article_views', false); + + // Make sure the parent is valid and get info about it + $db = JFactory::getDBO(); + + if ($parent_entity == 'category') + { + // Handle categories + $always_show_category_attachments = $aparams->get('always_show_category_attachments', false); + if ($always_show_category_attachments) + { + return false; + } + if ($all_but_article_views) + { + return true; + } + + // Check to see whether the attachments should be hidden for this category + $hide_attachments_for_categories = $aparams->get('hide_attachments_for_categories', Array()); + if (in_array($parent_id, $hide_attachments_for_categories)) + { + return true; + } + + // Make sure a category with this ID exists + $query = $db->getQuery(true); + $query->select('id')->from('#__categories'); + $query->where('id = ' . (int) $parent_id); + $db->setQuery($query, 0, 1); + $result = (int) $db->loadResult(); + if ((int) $parent_id != $result) + { + return true; + } + } + + else + { + // Handle articles + if ($parent_id == 0) + { + return false; + } + + // Make sure we have a valid article + $query = $db->getQuery(true); + $query->select('created_by, catid')->from('#__content')->where('id = ' . (int) $parent_id); + $db->setQuery($query); + $attachments = $db->loadObjectList(); + if ($db->getErrorNum() || (count($attachments) === false)) + { + $errmsg = JText::sprintf('ATTACH_ERROR_INVALID_PARENT_S_ID_N', $parent_entity_name, $parent_id) . ' (ERR 410)'; + JError::raiseError(500, $errmsg); + } + + // Honor all_but_article_view option + $view = JRequest::getCmd('view'); + if ($all_but_article_views) + { + if ($view != 'article') + { + return true; + } + } + + // See if the options apply to this article + $created_by = (int) $attachments[0]->created_by; + $catid = (int) $attachments[0]->catid; + + // First, check to see whether the attachments should be hidden for this parent + $hide_attachments_for_categories = $aparams->get('hide_attachments_for_categories', Array()); + if (in_array($catid, $hide_attachments_for_categories)) + { + return true; + } + } + + // The default is: attachments are not hidden + 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 may add attachments to this parent + */ + public function userMayAddAttachment($parent_id, $parent_entity, $new_parent = false, $user_id = null) + { + require_once JPATH_ADMINISTRATOR . '/components/com_attachments/permissions.php'; + + $user = JFactory::getUser($user_id); + + // Handle each entity type + $parent_entity = $this->getCanonicalEntityId($parent_entity); + + switch ($parent_entity) + { + + case 'category': + + // First, determine if the user can edit this category + if (!AttachmentsPermissions::userMayEditCategory($parent_id)) + { + return false; + } + + // Finally, see if the user has permissions to create attachments + return $user->authorise('core.create', 'com_attachments'); + + break; + + default: + // For articles + + // First, determine if the user can edit this article + if (!AttachmentsPermissions::userMayEditArticle($parent_id)) + { + return false; + } + + // Finally, see if the user has permissions to create attachments + return $user->authorise('core.create', 'com_attachments'); + } + + // No one else is allowed to add attachments + return false; + } + + /** + * Return true if this user may edit (modify/update/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 these objects before calling this function.) + * + * @param &record &$attachment database reocrd 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) + { + // If the user generally has permissions to edit all content, they + // may edit this attachment (editor, publisher, admin, etc) + $user = JFactory::getUser($user_id); + if ($user->authorise('com_content', 'edit', 'content', 'all')) + { + return true; + } + + require_once JPATH_ADMINISTRATOR . '/components/com_attachments/permissions.php'; + + // Handle each entity type + + switch ($attachment->parent_entity) + { + + case 'category': + + // ?? Deal with parents being created (parent_id == 0) + + // First, determine if the user can edit this category + if (!AttachmentsPermissions::userMayEditCategory($attachment->parent_id)) + { + return false; + } + + // See if the user can edit any attachment + if ($user->authorise('core.edit', 'com_attachments')) + { + return true; + } + + // See if the user has permissions to edit their own attachments + if ($user->authorise('core.edit.own', 'com_attachments') && ((int) $user->id == (int) $attachment->created_by)) + { + return true; + } + + // See if the user has permission to edit attachments on their own cateogory + if ($user->authorise('attachments.edit.ownparent', 'com_attachments')) + { + $category_creator_id = $this->getParentCreatorId($attachment->parent_id, 'category'); + return (int) $user->id == (int) $category_creator_id; + } + + break; + + default: + // Articles + + // ?? Deal with parents being created (parent_id == 0) + + // First, determine if the user can edit this article + if (!AttachmentsPermissions::userMayEditArticle($attachment->parent_id)) + { + return false; + } + + // See if the user can edit any attachment + if ($user->authorise('core.edit', 'com_attachments')) + { + return true; + } + + // See if the user has permissions to edit their own attachments + if ($user->authorise('core.edit.own', 'com_attachments') && ((int) $user->id == (int) $attachment->created_by)) + { + return true; + } + + // See if the user has permission to edit attachments on their own article + if ($user->authorise('attachments.edit.ownparent', 'com_attachments')) + { + $article_creator_id = $this->getParentCreatorId($attachment->parent_id, 'article'); + return (int) $user->id == (int) $article_creator_id; + } + } + + return false; + } + + /** + * 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) + { + // If the user generally has permissions to edit ALL content, they + // may edit this attachment (editor, publisher, admin, etc) + $user = JFactory::getUser($user_id); + if ($user->authorise('com_content', 'edit', 'content', 'all')) + { + return true; + } + + require_once JPATH_ADMINISTRATOR . '/components/com_attachments/permissions.php'; + + // Handle each entity type + + switch ($attachment->parent_entity) + { + + case 'category': + + // First, determine if the user can edit this category + if (!AttachmentsPermissions::userMayEditCategory($attachment->parent_id)) + { + return false; + } + + // Ok if the user can delete any attachment + if ($user->authorise('core.delete', 'com_attachments')) + { + return true; + } + + // See if the user has edit.own and created it + if ($user->authorise('attachments.delete.own', 'com_attachments') && ((int) $user->id == (int) $attachment->created_by)) + { + return true; + } + + // See if the user has permission to delete any attachments for categories they created + if ($user->authorise('attachments.delete.ownparent', 'com_attachments')) + { + $category_creator_id = $this->getParentCreatorId($attachment->parent_id, 'category'); + return (int) $user->id == (int) $category_creator_id; + } + + break; + + default: // Articles + + // ?? Deal with parents being created (parent_id == 0) + + // First, determine if the user can edit this article + if (!AttachmentsPermissions::userMayEditArticle($attachment->parent_id)) + { + return false; + } + + // Ok if the user can delete any attachment + if ($user->authorise('core.delete', 'com_attachments')) + { + return true; + } + + // See if the user has permissions to delete their own attachments + if ($user->authorise('attachments.delete.own', 'com_attachments') && ((int) $user->id == (int) $attachment->created_by)) + { + return true; + } + + // See if the user has permission to delete any attachments for articles they created + if ($user->authorise('attachments.delete.ownparent', 'com_attachments')) + { + $article_creator_id = $this->getParentCreatorId($attachment->parent_id, 'article'); + return (int) $user->id == (int) $article_creator_id; + } + } + + return false; + } + + /** + * 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) + { + // If the user generally has permissions to edit all content, they + // may change this attachment state (editor, publisher, admin, etc) + $user = JFactory::getUser($user_id); + if ($user->authorise('com_content', 'edit', 'content', 'all')) + { + return true; + } + + require_once JPATH_ADMINISTRATOR . '/components/com_attachments/permissions.php'; + + // Handle each entity type + + switch ($parent_entity) + { + + case 'category': + + // ?? Deal with parents being created (parent_id == 0) + + // First, determine if the user can edit this category + if (!AttachmentsPermissions::userMayEditCategory($parent_id)) + { + return false; + } + + // See if the user can change the state of any attachment + if ($user->authorise('core.edit.state', 'com_attachments')) + { + return true; + } + + // See if the user has permissions to change the state of their own attachments + if ($user->authorise('attachments.edit.state.own', 'com_attachments') && ((int) $user->id == (int) $attachment_creator_id)) + { + return true; + } + + // See if the user has permission to change the state of any attachments for categories they created + if ($user->authorise('attachments.edit.state.ownparent', 'com_attachments')) + { + $category_creator_id = $this->getParentCreatorId($parent_id, 'category'); + return (int) $user->id == (int) $category_creator_id; + } + + break; + + default: + // Articles + + // ?? Deal with parents being created (parent_id == 0) + + // First, determine if the user can edit this article + if (!AttachmentsPermissions::userMayEditArticle($parent_id)) + { + return false; + } + + // See if the user can change the state of any attachment + if ($user->authorise('core.edit.state', 'com_attachments')) + { + return true; + } + + // See if the user has permissions to change the state of their own attachments + if ($user->authorise('attachments.edit.state.own', 'com_attachments') && ((int) $user->id == (int) $attachment_creator_id)) + { + return true; + } + + // See if the user has permission to edit the state of any attachments for articles they created + if ($user->authorise('attachments.edit.state.ownparent', 'com_attachments')) + { + $article_creator_id = $this->getParentCreatorId($parent_id, 'article'); + return (int) $user->id == (int) $article_creator_id; + } + } + + return false; + } + + /** 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) + { + $user = JFactory::getUser($user_id); + return in_array($attachment->access, $user->getAuthorisedViewLevels()); + } + + + /** 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) + { + return ($layout =='edit') && (($view == 'form') || ($view == 'article') || ($view == 'category')); + } + + /** 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) + { + $app = JFactory::getApplication(); + if ($app->isAdmin()) { + // The default works fine for the back end + return parent::getParentIdInEditor($parent_entity, $view, $layout); + } + + // Note categories cannot be created or edited from the frontend + if ($parent_entity == 'category') { + return false; + } + + // Deal with articles (in frontend) + $id = null; + if (($view == 'article') OR ($view == 'form')) { + $id = JRequest::getInt('a_id', $default=null); + } + else { + $id = false; + } + + // If we got one, convert it to an int + if (is_numeric($id)) { + $id = (int)$id; + } + + return $id; + } + + + /** 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() + { + return array_merge(parent::knownFroms(), Array('frontpage', 'featured', 'article', 'category', 'details')); + } + +} + + +/** Register this attachments type */ +$apm = getAttachmentsPluginManager(); +$apm->addParentType('com_content'); diff --git a/plugins/attachments/attachments_for_content/attachments_for_content.xml b/plugins/attachments/attachments_for_content/attachments_for_content.xml new file mode 100644 index 00000000..29d21dfb --- /dev/null +++ b/plugins/attachments/attachments_for_content/attachments_for_content.xml @@ -0,0 +1,21 @@ + + + plg_attachments_for_content + 3.2.6 + March 26, 2018 + Jonathan M. Cameron + jmcameron@jmcameron.net + http://joomlacode.org/gf/project/attachments/ + (C) 2009-2018 Jonathan M. Cameron. All rights reserved. + http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL + ATTACH_ATTACHMENTS_FOR_CONTENT_PLUGIN_DESCRIPTION + + install.php + + + attachments_for_content.php + index.html + language + + + diff --git a/plugins/attachments/attachments_for_content/index.html b/plugins/attachments/attachments_for_content/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/plugins/attachments/attachments_for_content/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/attachments/attachments_for_content/install.php b/plugins/attachments/attachments_for_content/install.php new file mode 100644 index 00000000..9a71e972 --- /dev/null +++ b/plugins/attachments/attachments_for_content/install.php @@ -0,0 +1,61 @@ +getQuery(true); + $query->update('#__extensions') + ->set("enabled = 0") + ->where('type=' . $db->quote('plugin') . ' AND name=' . $db->quote($plugin_name)); + $db->setQuery($query); + $db->query(); + + // NOTE: Do NOT complain if there was an error + // (in case any plugin is already uninstalled and this query fails) + } + } + +} diff --git a/plugins/attachments/attachments_for_content/language/en-GB/en-GB.plg_attachments_attachments_for_content.ini b/plugins/attachments/attachments_for_content/language/en-GB/en-GB.plg_attachments_attachments_for_content.ini new file mode 100644 index 00000000..a51baf55 --- /dev/null +++ b/plugins/attachments/attachments_for_content/language/en-GB/en-GB.plg_attachments_attachments_for_content.ini @@ -0,0 +1,14 @@ +; en-GB.plg_attachments_for_content.ini +; Attachments for Joomla! extension +; Copyright (C) 2009-2018 Jonathan M. Cameron, All rights reserved. +; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL +; Note : All ini files need to be saved as UTF-8 - No BOM + +; English translation + +ATTACH_ARTICLE="Article" +ATTACH_ARTICLES="Articles" +ATTACH_ATTACHMENTS_FOR_CONTENT_PLUGIN_DESCRIPTION="The Attachments for Content plugin enables adding attachments to content articles as well as category descriptions." +ATTACH_CATEGORY="Category" +ATTACH_CATEGORYS="Categories" +ATTACH_ERROR_UNRECOGNIZED_PARENT_STATE_S="ERROR: Unrecognized parent state (%s)" diff --git a/plugins/attachments/attachments_for_content/language/en-GB/en-GB.plg_attachments_attachments_for_content.sys.ini b/plugins/attachments/attachments_for_content/language/en-GB/en-GB.plg_attachments_attachments_for_content.sys.ini new file mode 100644 index 00000000..bf8004b4 --- /dev/null +++ b/plugins/attachments/attachments_for_content/language/en-GB/en-GB.plg_attachments_attachments_for_content.sys.ini @@ -0,0 +1,10 @@ +; en-GB.plg_attachments_for_content.sys.ini +; Attachments for Joomla! extension +; Copyright (C) 2009-2018 Jonathan M. Cameron, All rights reserved. +; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL +; Note : All ini files need to be saved as UTF-8 - No BOM + +; English translation + +ATTACH_ATTACHMENTS_FOR_CONTENT_PLUGIN_DESCRIPTION="The Attachments for Content plugin enables adding attachments to content articles as well as category descriptions." +PLG_ATTACHMENTS_FOR_CONTENT="Attachments - For Content" diff --git a/plugins/attachments/attachments_for_content/language/en-GB/index.html b/plugins/attachments/attachments_for_content/language/en-GB/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/plugins/attachments/attachments_for_content/language/en-GB/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/attachments/attachments_for_content/language/index.html b/plugins/attachments/attachments_for_content/language/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/plugins/attachments/attachments_for_content/language/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/attachments/attachments_for_content/language/it-IT/index.html b/plugins/attachments/attachments_for_content/language/it-IT/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/plugins/attachments/attachments_for_content/language/it-IT/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/attachments/attachments_for_content/language/it-IT/it-IT.plg_attachments_attachments_for_content.ini b/plugins/attachments/attachments_for_content/language/it-IT/it-IT.plg_attachments_attachments_for_content.ini new file mode 100644 index 00000000..0014089d --- /dev/null +++ b/plugins/attachments/attachments_for_content/language/it-IT/it-IT.plg_attachments_attachments_for_content.ini @@ -0,0 +1,14 @@ +; it-IT.plg_attachments_for_content.ini +; Attachments for Joomla! extension +; Copyright (C) 2009-2013 Jonathan M. Cameron, All rights reserved. +; License GNU GPL 3: http://www.gnu.org/licenses/gpl-3.0.html +; Note : All ini files need to be saved as UTF-8 - No BOM + +; Italian translation by: Piero Mattirolo (2.0, 3.0), Lemminkainen (version 1.3.4) + +ATTACH_ARTICLE="Articolo" +ATTACH_ARTICLES="Articoli" +ATTACH_ATTACHMENTS_FOR_CONTENT_PLUGIN_DESCRIPTION="Questo plugin permette di aggiungere allegati agli articoli, come pure alle descrizioni di categorie." +ATTACH_CATEGORY="Categoria" +ATTACH_CATEGORYS="Categorie" +ATTACH_ERROR_UNRECOGNIZED_PARENT_STATE_S="ERROR: Stato del genitore non riconosciuto(%s)" diff --git a/plugins/attachments/attachments_for_content/language/it-IT/it-IT.plg_attachments_attachments_for_content.sys.ini b/plugins/attachments/attachments_for_content/language/it-IT/it-IT.plg_attachments_attachments_for_content.sys.ini new file mode 100644 index 00000000..706ee1af --- /dev/null +++ b/plugins/attachments/attachments_for_content/language/it-IT/it-IT.plg_attachments_attachments_for_content.sys.ini @@ -0,0 +1,10 @@ +; it-IT.plg_attachments_for_content.sys.ini +; Attachments for Joomla! extension +; Copyright (C) 2009-2013 Jonathan M. Cameron, All rights reserved. +; License GNU GPL 3: http://www.gnu.org/licenses/gpl-3.0.html +; Note : All ini files need to be saved as UTF-8 - No BOM + +; Italian translation by: Piero Mattirolo (2.0, 3.0), Lemminkainen (version 1.3.4) + +ATTACH_ATTACHMENTS_FOR_CONTENT_PLUGIN_DESCRIPTION="Questo plugin permette di aggiungere allegati agli articoli, come pure alle descrizioni di categorie." +PLG_ATTACHMENTS_FOR_CONTENT="Allegati - Per contenuti" diff --git a/plugins/attachments/attachments_plugin_framework/attachments_plugin.php b/plugins/attachments/attachments_plugin_framework/attachments_plugin.php new file mode 100644 index 00000000..38ca6009 --- /dev/null +++ b/plugins/attachments/attachments_plugin_framework/attachments_plugin.php @@ -0,0 +1,1098 @@ + + * @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 = "&parent_type=" . $this->parent_type; + + if ($parent_entity != 'default') + { + $entity .= '.' . $parent_entity; + } + + return "index.php?option=com_attachments&task=selectEntity" . $entity . "&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('@()?{attachments([ ]*:*[^}]+)?}()?@', $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
\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 = "
\n" . $html . "\n
"; + } + + // 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 = '
get('_name') == 'tinymce') { + # Hack because TinyMCE changed the structure + $reptag = '
+ * @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'); + +/** + * Get the singleton plugin manager for attachments + * + * @return the plugin manager singleton object + */ +function &getAttachmentsPluginManager() +{ + static $instance; + + if (!is_object($instance)) + { + require_once dirname(__FILE__) . '/attachments_plugin_manager.php'; + $instance = new AttachmentsPluginManager; + } + + return $instance; +} + + +/** Make sure the plugin class is loaded for derived classes */ +require_once dirname(__FILE__) . '/attachments_plugin.php'; diff --git a/plugins/attachments/attachments_plugin_framework/attachments_plugin_framework.xml b/plugins/attachments/attachments_plugin_framework/attachments_plugin_framework.xml new file mode 100644 index 00000000..0f6b18bf --- /dev/null +++ b/plugins/attachments/attachments_plugin_framework/attachments_plugin_framework.xml @@ -0,0 +1,23 @@ + + + plg_attachments_plugin_framework + 3.2.6 + March 26, 2018 + Jonathan M. Cameron + jmcameron@jmcameron.net + http://joomlacode.org/gf/project/attachments/ + (C) 2009-2018 Jonathan M. Cameron. All rights reserved. + http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL + ATTACH_ATTACHMENTS_FOR_COMPONENTS_PLUGIN_FRAMEWORK_DESCRIPTION + + install.php + + + attachments_plugin_framework.php + attachments_plugin.php + attachments_plugin_manager.php + index.html + language + + + diff --git a/plugins/attachments/attachments_plugin_framework/attachments_plugin_manager.php b/plugins/attachments/attachments_plugin_framework/attachments_plugin_manager.php new file mode 100644 index 00000000..e8a98b30 --- /dev/null +++ b/plugins/attachments/attachments_plugin_framework/attachments_plugin_manager.php @@ -0,0 +1,224 @@ + + * @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'); + + +/** + * The class for the manager for attachments plugins + * + * AttachmentsPluginManager manages plugins for Attachments. + * It knows how to create handlers for plugins for all + * supported extensions. + * + * @package Attachments + * @since 3.0 + */ +class AttachmentsPluginManager extends JObject +{ + /** A list of known parent_type names + */ + private $parent_types = Array(); + + /** An array of info about the installed entities. + * Each item in the array is an associative array with the following entries: + * 'id' - the unique name of entity as stored in the jos_attachments table (all lower case) + * 'name' - the translated name of the entity + * 'name_plural' - the translated plural name of the entity + * 'parent_type' - the parent type for the entity + */ + private $entity_info = Array(); + + /** An associative array of attachment plugins + */ + private $plugin = Array(); + + /** Flag indicating if the language file haas been loaded + */ + private $language_loaded = false; + + /** + * Constructor + */ + public function __construct() + { + parent::__construct(); + $this->loadLanguage(); + } + + /** + * See if a particular plugin is installed (avaliable) + * + * @param string $parent_type the name of the parent extension (eg, com_content) + * + * @return Boolean true if the plugin is available (false if not) + */ + public function attachmentsPluginInstalled($parent_type) + { + return in_array($parent_type, $this->parent_types); + } + + /** + * Check to see if an attachments plugin is enabled + * + * @param string $parent_type the name of the parent extension (eg, com_content) + * + * @return true if the attachment is enabled (false if disabled) + */ + public function attachmentsPluginEnabled($parent_type) + { + // Extract the component name (the part after 'com_') + if (strpos($parent_type, 'com_') == 0) + { + $name = substr($parent_type, 4); + + return JPluginHelper::isEnabled('attachments', "attachments_for_$name"); + } + + // If the parent type does not conform to the naming convention, assume it is not enabled + return false; + } + + /** + * Add a new parent type + * + * @param string $new_parent_type the name of the new parent extension (eg, com_content) + * + * @return nothing + */ + public function addParentType($new_parent_type) + { + if (in_array($new_parent_type, $this->parent_types)) + { + return; + } + else + { + $this->parent_types[] = $new_parent_type; + } + } + + /** + * Return the list of installed parent types + * + * @return an array of the installed parent types + */ + public function &getInstalledParentTypes() + { + return $this->parent_types; + } + + /** + * Return the list of installed parent entities + * + * @return array of entity info (see var $_entity_info definition above) + */ + public function &getInstalledEntityInfo() + { + if (count($this->entity_info) == 0) + { + // Add an option for each entity + JPluginHelper::importPlugin('attachments'); + $apm = getAttachmentsPluginManager(); + + // Process all the parent types + foreach ($this->parent_types as $parent_type) + { + $parent = $apm->getAttachmentsPlugin($parent_type); + $entities = $parent->getEntities(); + + // Process each entity for this parent type + foreach ($entities as $entity) + { + $centity = $parent->getCanonicalEntityId($entity); + $this->entity_info[] = array( + 'id' => $centity, + 'name' => JText::_('ATTACH_' . $centity), + 'name_plural' => JText::_('ATTACH_' . $centity . 's'), + 'parent_type' => $parent_type + ); + } + } + } + + return $this->entity_info; + } + + /** + * Load the langauge for this parent type + * + * @return true of the language was loaded successfullly + */ + public function loadLanguage() + { + if ($this->language_loaded) + { + return true; + } + + $lang = JFactory::getLanguage(); + + $this->language_loaded = $lang->load('plg_attachments_attachments_plugin_framework', dirname(__FILE__)); + + return $this->language_loaded; + } + + /** + * Get the plugin (attachments parent handler object) + * + * @param string $parent_type the name of the parent extension (eg, com_content) + * + * @return the parent handler object + */ + public function getAttachmentsPlugin($parent_type) + { + // Make sure the parent type is valid + if (!in_array($parent_type, $this->parent_types)) + { + $errmsg = JText::sprintf('ATTACH_ERROR_UNKNOWN_PARENT_TYPE_S', $parent_type) . ' (ERR 303)'; + JError::raiseError(406, $errmsg); + } + + // Instantiate the plugin object, if we have not already done it + if (!array_key_exists($parent_type, $this->plugin)) + { + $this->installPlugin($parent_type); + } + + return $this->plugin[$parent_type]; + } + + /** + * Install the specified plugin + * + * @param string $parent_type the name of the parent extension (eg, com_content) + * + * @return true if successful (false if not) + */ + private function installPlugin($parent_type) + { + // Do nothing if the plugin is already installed + if (array_key_exists($parent_type, $this->plugin)) + { + return true; + } + + // Install the plugin + $dispatcher = JDispatcher::getInstance(); + $className = 'AttachmentsPlugin_' . $parent_type; + $this->plugin[$parent_type] = new $className($dispatcher); + + return is_object($this->plugin[$parent_type]); + } +} diff --git a/plugins/attachments/attachments_plugin_framework/index.html b/plugins/attachments/attachments_plugin_framework/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/plugins/attachments/attachments_plugin_framework/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/attachments/attachments_plugin_framework/install.php b/plugins/attachments/attachments_plugin_framework/install.php new file mode 100644 index 00000000..a45e1d48 --- /dev/null +++ b/plugins/attachments/attachments_plugin_framework/install.php @@ -0,0 +1,61 @@ +getQuery(true); + $query->update('#__extensions') + ->set("enabled = 0") + ->where('type=' . $db->quote('plugin') . ' AND name=' . $db->quote($plugin_name)); + $db->setQuery($query); + $db->query(); + + // NOTE: Do NOT complain if there was an error + // (in case any plugin is already uninstalled and this query fails) + } + } + +} diff --git a/plugins/attachments/attachments_plugin_framework/language/en-GB/en-GB.plg_attachments_attachments_plugin_framework.ini b/plugins/attachments/attachments_plugin_framework/language/en-GB/en-GB.plg_attachments_attachments_plugin_framework.ini new file mode 100644 index 00000000..4aaf0958 --- /dev/null +++ b/plugins/attachments/attachments_plugin_framework/language/en-GB/en-GB.plg_attachments_attachments_plugin_framework.ini @@ -0,0 +1,15 @@ +; en-GB.plg_attachments_plugin_framework.ini +; Attachments for Joomla! extension +; Copyright (C) 2009-2018 Jonathan M. Cameron, All rights reserved. +; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL +; Note : All ini files need to be saved as UTF-8 - No BOM + +; English translation + +ATTACH_ADD_ATTACHMENT_TO="Add Attachment to:" +ATTACH_ATTACHMENTS_FOR_COMPONENTS_PLUGIN_FRAMEWORK_DESCRIPTION="The Attachments plugin framework plugin provides the plugin framework that enables adding attachments to the content parts of various types of components." +ATTACH_ERROR_BAD_ENTITY_S_ID="ERROR: Unable to get valid %s ID!" +ATTACH_ERROR_GETTING_PARENT_S_TITLE_FOR_ID_N="Error getting %s title for ID %d!" +ATTACH_ERROR_INVALID_ENTITY_S_FOR_PARENT_S="ERROR: Invalid entity '%s' for parent '%s'!" +ATTACH_ERROR_INVALID_PARENT_S_ID_N="ERROR: Invalid %s parent ID (%d)!" +ATTACH_NOT_IMPLEMENTED="Not implemented!" diff --git a/plugins/attachments/attachments_plugin_framework/language/en-GB/en-GB.plg_attachments_attachments_plugin_framework.sys.ini b/plugins/attachments/attachments_plugin_framework/language/en-GB/en-GB.plg_attachments_attachments_plugin_framework.sys.ini new file mode 100644 index 00000000..06fb4af0 --- /dev/null +++ b/plugins/attachments/attachments_plugin_framework/language/en-GB/en-GB.plg_attachments_attachments_plugin_framework.sys.ini @@ -0,0 +1,10 @@ +; en-GB.plg_attachments_plugin_framework.sys.ini +; Attachments for Joomla! extension +; Copyright (C) 2009-2018 Jonathan M. Cameron, All rights reserved. +; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL +; Note : All ini files need to be saved as UTF-8 - No BOM + +; English translation + +ATTACH_ATTACHMENTS_FOR_COMPONENTS_PLUGIN_FRAMEWORK_DESCRIPTION="The Attachments plugin framework plugin provides the plugin framework that enables adding attachments to the content parts of various types of components." +PLG_ATTACHMENTS_PLUGIN_FRAMEWORK="Attachments - Plugin Framework" diff --git a/plugins/attachments/attachments_plugin_framework/language/en-GB/index.html b/plugins/attachments/attachments_plugin_framework/language/en-GB/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/plugins/attachments/attachments_plugin_framework/language/en-GB/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/attachments/attachments_plugin_framework/language/index.html b/plugins/attachments/attachments_plugin_framework/language/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/plugins/attachments/attachments_plugin_framework/language/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/attachments/attachments_plugin_framework/language/it-IT/index.html b/plugins/attachments/attachments_plugin_framework/language/it-IT/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/plugins/attachments/attachments_plugin_framework/language/it-IT/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/attachments/attachments_plugin_framework/language/it-IT/it-IT.plg_attachments_attachments_plugin_framework.ini b/plugins/attachments/attachments_plugin_framework/language/it-IT/it-IT.plg_attachments_attachments_plugin_framework.ini new file mode 100644 index 00000000..92b6e938 --- /dev/null +++ b/plugins/attachments/attachments_plugin_framework/language/it-IT/it-IT.plg_attachments_attachments_plugin_framework.ini @@ -0,0 +1,15 @@ +; it-IT.plg_attachments_plugin_framework.ini +; Attachments for Joomla! extension +; Copyright (C) 2009-2013 Jonathan M. Cameron, All rights reserved. +; License GNU GPL 3: http://www.gnu.org/licenses/gpl-3.0.html +; Note : All ini files need to be saved as UTF-8 - No BOM + +; Italian translation by: Piero Mattirolo (2.0, 3.0), Lemminkainen (version 1.3.4) + +ATTACH_ADD_ATTACHMENT_TO="Aggiungi allegato a:" +ATTACH_ATTACHMENTS_FOR_COMPONENTS_PLUGIN_FRAMEWORK_DESCRIPTION="Questo plugin fornisce il framework di plugin che permette di aggiungere allegati a segmenti di contenuto di vari tipi di componenti." +ATTACH_ERROR_BAD_ENTITY_S_ID="ERRORE: Impossibile ottenere ID %s valida!" +ATTACH_ERROR_GETTING_PARENT_S_TITLE_FOR_ID_N="Errore nell'ottenere %s titolo per ID %d!" +ATTACH_ERROR_INVALID_ENTITY_S_FOR_PARENT_S="ERRORE: Entità non valida '%s' per genitore '%s'!" +ATTACH_ERROR_INVALID_PARENT_S_ID_N="ERROR: ID genitore %(i) non valida (%e)!" +ATTACH_NOT_IMPLEMENTED="Non implementato!" diff --git a/plugins/attachments/attachments_plugin_framework/language/it-IT/it-IT.plg_attachments_attachments_plugin_framework.sys.ini b/plugins/attachments/attachments_plugin_framework/language/it-IT/it-IT.plg_attachments_attachments_plugin_framework.sys.ini new file mode 100644 index 00000000..912c36f0 --- /dev/null +++ b/plugins/attachments/attachments_plugin_framework/language/it-IT/it-IT.plg_attachments_attachments_plugin_framework.sys.ini @@ -0,0 +1,10 @@ +; it-IT.plg_attachments_plugin_framework.sys.ini +; Attachments for Joomla! extension +; Copyright (C) 2009-2013 Jonathan M. Cameron, All rights reserved. +; License GNU GPL 3: http://www.gnu.org/licenses/gpl-3.0.html +; Note : All ini files need to be saved as UTF-8 - No BOM + +; Italian translation by: Piero Mattirolo (2.0, 3.0), Lemminkainen (version 1.3.4) + +ATTACH_ATTACHMENTS_FOR_COMPONENTS_PLUGIN_FRAMEWORK_DESCRIPTION="Questo plugin fornisce il framework di plugin che permette di aggiungere allegati a segmenti di contenuto di vari tipi di componenti." +PLG_ATTACHMENTS_PLUGIN_FRAMEWORK="Allegati - Framework del Plugin" diff --git a/plugins/content/attachments/attachments.php b/plugins/content/attachments/attachments.php new file mode 100644 index 00000000..3c6975b6 --- /dev/null +++ b/plugins/content/attachments/attachments.php @@ -0,0 +1,424 @@ + + * @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/ + */ + +defined('_JEXEC') or die('Restricted access'); + +/** Load the Attachments defines (if available) */ +if (file_exists(JPATH_SITE . '/components/com_attachments/defines.php')) +{ + require_once JPATH_SITE . '/components/com_attachments/defines.php'; + require_once(JPATH_SITE . '/components/com_attachments/helper.php'); + require_once(JPATH_SITE . '/components/com_attachments/javascript.php'); +} +else +{ + // Exit quietly if the attachments component has been uninstalled or deleted + return; +} + + +/** + * Attachments plugin + * + * @package Attachments + * @since 1.3.4 + */ +class plgContentAttachments extends JPlugin +{ + /** + * Constructor + * + * @param object &$subject The object to observe + * @param array $config An array that holds the plugin configuration + * + * @access protected + */ + public function __construct(&$subject, $config) + { + parent::__construct($subject, $config); + + // Save this page's URL + $uri= JFactory::getURI(); + $return = '&return=' . urlencode(base64_encode(JUri::current() . '?' . $uri->getQuery())); + $app = JFactory::getApplication(); + $app->setUserState('com_attachments.current_url', $return); + + $this->loadLanguage(); + } + + /** + * The content plugin that inserts the attachments list into content items + * + * @param string The context of the content being passed to the plugin. + * @param &object &$row the content object (eg, article) being displayed + * @param &object &$params the parameters + * @param int $page the 'page' number + * + * @return true if anything has been inserted into the content object + */ + public function onContentPrepare($context, &$row, &$params, $page = 0) + { + // Enable the following four diagnostic lines to see if a component uses onContentPrepare + // $msg = "
onContentPrepare: CONTEXT: $context, OBJ: " . get_class($row) . ", VIEW: " . JRequest::getCmd('view'); + // if (isset($row->text)) $row->text .= $msg; + // if (isset($row->introtext)) $row->introtext .= $msg; + // return; + + // Set the parent info from the context + if (strpos($context, '.') === false) + { + // Assume the context is the parent_type + $parent_type = $context; + $parent_entity = 'default'; + } + else + { + list ($parent_type, $parent_entity) = explode('.', $context, 2); + } + + // This callback handles everything but articles + if ( $parent_type == 'com_content' ) + { + if (in_array($parent_entity, Array('featured', 'article'))) { + return false; + } + if ($parent_entity == 'category.title') { + // Do not add attachments to categtory titles (Joomla 3 only) + return false; + } + if (($parent_entity == 'category') AND (isset($row->catid))) { + // Ignore the callback for articles on category blogs + if (version_compare(JVERSION, '3.4.0', 'lt')) { + return false; + } + } + + $parent_entity = 'category'; + + // Older versions of Joomla do not deal well with category lists and + // it is necessary to use the show_attachments callback to display + // category descriptions in those cases. + if (version_compare(JVERSION, '2.5.10', 'lt') OR + (version_compare(JVERSION, '3.0', 'ge') AND version_compare(JVERSION, '3.1', 'lt'))) { + return false; + } + } + + $view = JRequest::getCmd('view'); + $layout = JRequest::getCmd('layout'); + + if ( ($parent_type == 'mod_custom') AND ($parent_entity == 'content') AND ($view == 'category') ) + { + // Do not add attachments to categtory titles (Joomla 3.4+) + return false; + } + + // Handle category blog articles specially + if (($context == 'com_content.category') AND ($view == 'category') AND ($layout == 'blog')) { + if (isset($row->id) and is_numeric($row->id)) { + $parent_entity = 'article'; + } + } + if (version_compare(JVERSION, '3.7.0')) + { + # Ignore this for Joomla 3.7.0+ (seems to be new and category attachments are handled ok without it) + if ($context == 'com_content.categories') + return false; + } + + // Get the article/parent handler + JPluginHelper::importPlugin('attachments'); + $apm = getAttachmentsPluginManager(); + if ( !$apm->attachmentsPluginInstalled($parent_type) ) { + // Exit quietly if there is no Attachments plugin to handle this parent_type + return false; + } + $parent = $apm->getAttachmentsPlugin($parent_type); + + // If this attachments plugin is disabled, skip it + if ( ! $apm->attachmentsPluginEnabled($parent_type) ) { + return false; + } + + // Get the parent ID + $parent_id = null; + if (isset($row->id) and is_numeric($row->id)) + { + // If the $row has 'id', just use it + $parent_id = (int)$row->id; + } + else if ($parent_entity == 'category') + { + $db = JFactory::getDBO(); + $description = $row->text; + $query = $db->getQuery(true); + $query->select('id')->from('#__categories'); + $query->where('description=' . $db->quote($description)); + $db->setQuery($query, 0, 1); + $result = $db->loadResult(); + if ($result) { + $parent_id = (int)$result; + } + } + + // Let the attachment pluging try to figure out the id + if ( $parent_id === null ) + { + $parent_id = $parent->getParentId($row); + } + + if ( $parent_id === null ) + { + return false; + } + + // Load the language + $lang = JFactory::getLanguage(); + $lang->load('plg_content_attachments', dirname(__FILE__)); + + // Set up the refresh behavior + AttachmentsJavascript::setupJavascript(); + + // Always include the hide rule (since it may be needed to hide the custom tags) + JHtml::stylesheet('com_attachments/attachments_hide.css', Array(), true); + + // Allow remapping of parent ID (eg, for Joomfish) + if (jimport('attachments_remapper.remapper')) + { + $parent_id = AttachmentsRemapper::remapParentID($parent_id, $parent_type, $parent_entity); + } + + // Exit if we should not display attachments for this parent + if ( $parent->attachmentsHiddenForParent($row, $parent_id, $parent_entity) ) { + return false; + } + + // Get the component parameters + jimport('joomla.application.component.helper'); + $attachParams = JComponentHelper::getParams('com_attachments'); + + // Make sure we should be showing the category attachments + $always_show_category_attachments = $attachParams->get('always_show_category_attachments', false); + $all_but_article_views = $attachParams->get('hide_except_article_views', false); + if ( $all_but_article_views && !$always_show_category_attachments ) { + return false; + } + + // Add the attachments list + $parent->insertAttachmentsList($row, $parent_id, $parent_entity); + + // FOR DEBUGGING + // if (isset($row->text)) $row->text .= " [AP text CONTEXT($context) PE($parent_entity) ]"; + // if (isset($row->introtext)) $row->introtext .= " [AP introtext CONTEXT($context) PE($parent_entity)]"; + + return true; + } + + + /** + * The content plugin that inserts the attachments list into content items + * + * @param string $context the context of the content being passed to the plugin. + * @param &object &$row the content object (eg, article) being displayed + * @param &object &$params the parameters + * @param int $page the 'page' number + * + * @return true if anything has been inserted into the content object + */ + public function onContentBeforeDisplay($context, &$row, &$params, $page = 0) + { + $view = JRequest::getCmd('view'); + $layout = JRequest::getCmd('layout'); + if (($context == 'com_content.category') AND ($view == 'category') AND ($layout == 'blog')) { + // Use onContentPrepare for category blog articles for Joomla 3.4+ + if (version_compare(JVERSION, '3.4', 'ge')) { + return false; + } + } + + // Set the parent info from the context + if (strpos($context, '.') === false) + { + // Assume the context is the parent_type + $parent_type = $context; + $parent_entity = ''; + } + else + { + list ($parent_type, $parent_entity) = explode('.', $context, 2); + } + + // ??? Do we need to filter to ensure only articles use this callback? + + // Load the language + $lang = JFactory::getLanguage(); + $lang->load('plg_content_attachments', dirname(__FILE__)); + + // Add the refresh javascript + AttachmentsJavascript::setupJavascript(); + + // Always include the hide rule (since it may be needed to hide the custom tags) + JHtml::stylesheet('com_attachments/attachments_hide.css', array(), true); + + // Get the article/parent handler + JPluginHelper::importPlugin('attachments'); + $apm = getAttachmentsPluginManager(); + + if (!$apm->attachmentsPluginInstalled($parent_type)) + { + // Exit quietly if there is no Attachments plugin to handle this parent_type + return false; + } + $parent = $apm->getAttachmentsPlugin($parent_type); + + // If this attachments plugin is disabled, skip it + if (!$apm->attachmentsPluginEnabled($parent_type)) + { + return false; + } + + // Figure out the parent entity + $parent_entity = $parent->determineParentEntity($row); + + if (!$parent_entity) + { + return false; + } + + // Get the parent ID + $parent_id = null; + if (isset( $row->id ) && ($row->id > 0)) { + $parent_id = (int) $row->id; + } else { + $parent_id = $parent->getParentId($row); + } + + // Exit if there is no parent + if ($parent_id === false) + { + return false; + } + + // Allow remapping of parent ID (eg, for Joomfish) + if (jimport('attachments_remapper.remapper')) + { + $parent_id = AttachmentsRemapper::remapParentID($parent_id, $parent_type, $parent_entity); + } + + // Exit if we should not display attachments for this parent + if ($parent->attachmentsHiddenForParent($row, $parent_id, $parent_entity)) + { + return false; + } + + // Add the attachments list + $parent->insertAttachmentsList($row, $parent_id, $parent_entity); + + // ??? if (isset($row->text)) $row->text .= " [OCBD text $context]"; + // ??? if (isset($row->introtext)) $row->introtext .= " [OCBD introtext $context]"; + + return; + } + + + + + /** + * Set the parent_id for all attachments that were added to this + * content before it was saved the first time. + * + * This method is called right after the content is saved. + * + * @param string The context of the content being passed to the plugin. + * @param object $item A JTableContent object + * @param bool $isNew If the content is newly created + * + * @return void + */ + function onContentAfterSave($context, $item, $isNew ) + { + if ( !$isNew ) { + // If the item is not new, this step is not needed + return true; + } + + $ctxinfo = explode('.', $context); + $parent_type = $ctxinfo[0]; + $parent_entity = $ctxinfo[1]; + + // Special handling for categories + if ( $parent_type == 'com_categories' ) { + $parent_type = 'com_content'; + } + + // Get the attachments associated with this newly created item. + // NOTE: We assume that all attachments that have parent_id=null + // and are created by the current user are for this item. + $user = JFactory::getUser(); + $user_id = $user->get('id'); + + $db = JFactory::getDBO(); + $query = $db->getQuery(true); + $query->select('*')->from('#__attachments'); + $query->where('created_by=' . (int) $user_id . ' AND parent_id IS NULL'); + $db->setQuery($query); + $attachments = $db->loadObjectList(); + if ( $db->getErrorNum() ) { + $errmsg = $db->stderr() . ' (ERR 200)'; + JError::raiseError(500, $errmsg); + } + + // Exit if there are no new attachments + if ( count($attachments) == 0 ) { + return true; + } + + // Change the attachment to the new content item! + JTable::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_attachments/tables'); + $atrow = JTable::getInstance('Attachment', 'AttachmentsTable'); + + foreach ($attachments as $attachment) { + + // Fix for odd issue; on some systems, something is changing the + // parent_type in or out of the database + if ( ($attachment->parent_type) == 'com_media' AND + ($attachment->parent_entity) == 'article' ) { + // Override/fix the incorrect parent type + $attachment->parent_type = 'com_content'; + } + + // Change the filename/URL as necessary + $error_msg = AttachmentsHelper::switch_parent($attachment, null, $item->id); + if ( $error_msg != '' ) { + $errmsg = JText::_($error_msg) . ' (ERR 201)'; + JError::raiseError(500, $errmsg); + } + + // Update the parent info + $atrow->load($attachment->id); + $atrow->parent_id = $item->id; + $atrow->parent_type = $parent_type; + $atrow->filename_sys = $attachment->filename_sys; + $atrow->url = $attachment->url; + + if ( !$atrow->store() ) { + $errmsg = $attachment->getError() . ' (ERR 202)'; + JError::raiseError(500, $errmsg); + } + } + + return true; + } + + +} diff --git a/plugins/content/attachments/attachments.xml b/plugins/content/attachments/attachments.xml new file mode 100644 index 00000000..e23d2cf7 --- /dev/null +++ b/plugins/content/attachments/attachments.xml @@ -0,0 +1,21 @@ + + + plg_content_attachments + 3.2.6 + March 26, 2018 + Jonathan M. Cameron + jmcameron@jmcameron.net + http://joomlacode.org/gf/project/attachments/ + (C) 2007-2018 Jonathan M. Cameron. All rights reserved. + http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL + ATTACH_ATTACHMENTS_PLUGIN_DESCRIPTION + + install.php + + + attachments.php + index.html + language + + + diff --git a/plugins/content/attachments/index.html b/plugins/content/attachments/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/plugins/content/attachments/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/content/attachments/install.php b/plugins/content/attachments/install.php new file mode 100644 index 00000000..c79dcc27 --- /dev/null +++ b/plugins/content/attachments/install.php @@ -0,0 +1,61 @@ +getQuery(true); + $query->update('#__extensions') + ->set("enabled = 0") + ->where('type=' . $db->quote('plugin') . ' AND name=' . $db->quote($plugin_name)); + $db->setQuery($query); + $db->query(); + + // NOTE: Do NOT complain if there was an error + // (in case any plugin is already uninstalled and this query fails) + } + } + +} diff --git a/plugins/content/attachments/language/en-GB/en-GB.plg_content_attachments.ini b/plugins/content/attachments/language/en-GB/en-GB.plg_content_attachments.ini new file mode 100644 index 00000000..28ae4105 --- /dev/null +++ b/plugins/content/attachments/language/en-GB/en-GB.plg_content_attachments.ini @@ -0,0 +1,31 @@ +; en-GB.plg_frontend_attachments.ini +; Attachments for Joomla! extension +; Copyright (C) 2007-2018 Jonathan M. Cameron, All rights reserved. +; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL +; Note : All ini files need to be saved as UTF-8 - No BOM + +; English translation + +; Just for the front end display + +ATTACH_ACCESS_THIS_URL_S="Access this URL (%s)" +ATTACH_ADD_ATTACHMENT="Add attachment" +ATTACH_ATTACHMENTS="Attachments" +ATTACH_ATTACHMENTS_PLUGIN_DESCRIPTION="Attachments plugin: Displays a list of the attachments for article (or supported content item)," +ATTACH_ATTACHMENTS_TITLE="Attachments:" +ATTACH_CREATED="Created" +ATTACH_CREATOR="Creator" +ATTACH_DELETE_THIS_FILE="Delete this file" +ATTACH_DESCRIPTION="Description" +ATTACH_DOWNLOADS="Downloads" +ATTACH_DOWNLOAD_NOUN="Download" +ATTACH_DOWNLOAD_THIS_FILE_S="Download this file (%s)" +ATTACH_EXISTING_ATTACHMENTS="Existing Attachments:" +ATTACH_FILE="File" +ATTACH_FILE_SIZE="File size" +ATTACH_FILE_URL="File / URL" +ATTACH_S_KB="%s kB" +ATTACH_LAST_MODIFIED="Last modified" +ATTACH_REALLY_DELETE_ATTACHMENT="Really delete attachment?" +ATTACH_UPDATE_THIS_FILE="Update this file" +ATTACH_URL="URL" diff --git a/plugins/content/attachments/language/en-GB/en-GB.plg_content_attachments.sys.ini b/plugins/content/attachments/language/en-GB/en-GB.plg_content_attachments.sys.ini new file mode 100644 index 00000000..7c6d641f --- /dev/null +++ b/plugins/content/attachments/language/en-GB/en-GB.plg_content_attachments.sys.ini @@ -0,0 +1,12 @@ +; en-GB.plg_content_attachments.sys.ini +; Attachments for Joomla! extension +; Copyright (C) 2009-2018 Jonathan M. Cameron, All rights reserved. +; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL +; Note : All ini files need to be saved as UTF-8 - No BOM + +; English translation + +; For the plugin manager + +ATTACH_ATTACHMENTS_PLUGIN_DESCRIPTION="Attachments plugin: Displays a list of the attachments for article (or supported content item)," +PLG_CONTENT_ATTACHMENTS="Content - Attachments" diff --git a/plugins/content/attachments/language/en-GB/index.html b/plugins/content/attachments/language/en-GB/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/plugins/content/attachments/language/en-GB/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/content/attachments/language/index.html b/plugins/content/attachments/language/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/plugins/content/attachments/language/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/content/attachments/language/it-IT/index.html b/plugins/content/attachments/language/it-IT/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/plugins/content/attachments/language/it-IT/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/content/attachments/language/it-IT/it-IT.plg_content_attachments.ini b/plugins/content/attachments/language/it-IT/it-IT.plg_content_attachments.ini new file mode 100644 index 00000000..b788a582 --- /dev/null +++ b/plugins/content/attachments/language/it-IT/it-IT.plg_content_attachments.ini @@ -0,0 +1,30 @@ +; it-IT.plg_frontend_attachments.ini +; Attachments for Joomla! extension +; Copyright (C) 2007-2013 Jonathan M. Cameron, All rights reserved. +; License GNU GPL 3: http://www.gnu.org/licenses/gpl-3.0.html +; Note : All ini files need to be saved as UTF-8 - No BOM + +; Italian translation by: Piero Mattirolo (2.0, 3.0), Lemminkainen (version 1.3.4) + +; Just for the front end display + +ATTACH_ACCESS_THIS_URL_S="Accedi a questo URL (%s)" +ATTACH_ADD_ATTACHMENT="Aggiungi Allegato" +ATTACH_ATTACHMENTS="Allegati" +ATTACH_ATTACHMENTS_PLUGIN_DESCRIPTION="Allegati: questo plugin mostrerà una lista degli allegati disponibili per ciascun articolo (o elemento di contenuto supportato), " +ATTACH_ATTACHMENTS_TITLE="Allegati:" +ATTACH_CREATED="Creato" +ATTACH_CREATOR="Autore" +ATTACH_DELETE_THIS_FILE="Cancella questo file" +ATTACH_DESCRIPTION="Descrizione" +ATTACH_DOWNLOADS="Downloads" +ATTACH_DOWNLOAD_NOUN="Download" +ATTACH_DOWNLOAD_THIS_FILE_S="Scarica questo file (%s)" +ATTACH_EXISTING_ATTACHMENTS="Allegati Esistenti" +ATTACH_FILE="File" +ATTACH_FILE_SIZE="Dimensione del File" +ATTACH_FILE_URL="File / URL" +ATTACH_LAST_MODIFIED="Modificato il" +ATTACH_REALLY_DELETE_ATTACHMENT="Confermi la cancellazione dell'allegato?" +ATTACH_UPDATE_THIS_FILE="Aggiorna questo file" +ATTACH_URL="URL:" diff --git a/plugins/content/attachments/language/it-IT/it-IT.plg_content_attachments.sys.ini b/plugins/content/attachments/language/it-IT/it-IT.plg_content_attachments.sys.ini new file mode 100644 index 00000000..c5754c39 --- /dev/null +++ b/plugins/content/attachments/language/it-IT/it-IT.plg_content_attachments.sys.ini @@ -0,0 +1,12 @@ +; it-IT.plg_content_attachments.sys.ini +; Attachments for Joomla! extension +; Copyright (C) 2009-2013 Jonathan M. Cameron, All rights reserved. +; License GNU GPL 3: http://www.gnu.org/licenses/gpl-3.0.html +; Note : All ini files need to be saved as UTF-8 - No BOM + +; Italian translation by: Piero Mattirolo (2.0, 3.0), Lemminkainen (version 1.3.4) + +; For the plugin manager + +ATTACH_ATTACHMENTS_PLUGIN_DESCRIPTION="Plugin allegati: visualizza una lista degli allegati per ogni articolo (o elemento di contenuto supportato)," +PLG_CONTENT_ATTACHMENTS="Contenuto - Allegati" diff --git a/plugins/quickicon/attachments/attachments.php b/plugins/quickicon/attachments/attachments.php new file mode 100644 index 00000000..064630e7 --- /dev/null +++ b/plugins/quickicon/attachments/attachments.php @@ -0,0 +1,87 @@ +loadLanguage(); + } + + + /** + * This method is called when the Quick Icons module is constructing its set + * of icons. You can return an array which defines a single icon and it will + * be rendered right after the stock Quick Icons. + * + * @param $context The calling context + * + * @return array A list of icon definition associative arrays, consisting of the + * keys link, image, text and access. + * + * @since 2.5 + */ + public function onGetIcons($context) + { + // See if we should show the icon + if ($context != $this->params->get('context', 'mod_quickicon') || + !JFactory::getUser()->authorise('core.manage', 'com_attachments')) + { + return; + } + + // Add the CSS file + JHtml::stylesheet('com_attachments/attachments_quickicon.css', array(), true); + + if (version_compare(JVERSION, '3.0', 'ge')) + { + $image = 'flag-2'; + $icon = JUri::root() . '/media/com_attachments/images/attachments_logo48.png'; + } + else + { + $image = JUri::root() . '/media/com_attachments/images/attachments_logo48.png'; + $icon = ''; + } + + // Return the icon info for the quickicon system + return + array( + array( + 'link' => 'index.php?option=com_attachments', + 'image' => $image, + 'icon' => $icon, + 'text' => JText::_('PLG_QUICKICON_ATTACHMENTS_ICON'), + 'id' => 'plg_quickicon_attachment')); + } +} diff --git a/plugins/quickicon/attachments/attachments.xml b/plugins/quickicon/attachments/attachments.xml new file mode 100644 index 00000000..22e200ad --- /dev/null +++ b/plugins/quickicon/attachments/attachments.xml @@ -0,0 +1,29 @@ + + + plg_quickicon_attachments + 3.2.6 + March 26, 2018 + Jonathan M. Cameron + (C) 2007-2018 Jonathan M. Cameron. All rights reserved. + http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL + jmcameron@jmcameron.net + http://joomlacode.org/gf/project/attachments/ + PLG_QUICKICON_ATTACHMENTS_XML_DESCRIPTION + + attachments.php + index.html + language + + + +
+ +
+
+
+
diff --git a/plugins/quickicon/attachments/index.html b/plugins/quickicon/attachments/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/plugins/quickicon/attachments/index.html @@ -0,0 +1 @@ + diff --git a/plugins/quickicon/attachments/language/en-GB/en-GB.plg_quickicon_attachments.ini b/plugins/quickicon/attachments/language/en-GB/en-GB.plg_quickicon_attachments.ini new file mode 100644 index 00000000..40bc04f0 --- /dev/null +++ b/plugins/quickicon/attachments/language/en-GB/en-GB.plg_quickicon_attachments.ini @@ -0,0 +1,13 @@ +; en-GB.plg_quickicon_attachments.ini +; Attachments for Joomla! extension +; Copyright (C) 2007-2018 Jonathan M. Cameron, All rights reserved. +; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL +; Note : All ini files need to be saved as UTF-8 - No BOM + +; English translation + +PLG_QUICKICON_ATTACHMENTS="Quick Icon - Attachments" +PLG_QUICKICON_ATTACHMENTS_GROUP_DESC="The group of this plugin (this value is compared with the group value used in Quick Icons modules to inject icons)" +PLG_QUICKICON_ATTACHMENTS_GROUP_LABEL="Group" +PLG_QUICKICON_ATTACHMENTS_ICON="Attachments Manager" +PLG_QUICKICON_ATTACHMENTS_XML_DESCRIPTION="Manage the attachments for articles, categories, and other content types." diff --git a/plugins/quickicon/attachments/language/en-GB/en-GB.plg_quickicon_attachments.sys.ini b/plugins/quickicon/attachments/language/en-GB/en-GB.plg_quickicon_attachments.sys.ini new file mode 100644 index 00000000..fa0bb665 --- /dev/null +++ b/plugins/quickicon/attachments/language/en-GB/en-GB.plg_quickicon_attachments.sys.ini @@ -0,0 +1,10 @@ +; en-GB.plg_quickicon_attachments.sys.ini +; Attachments for Joomla! extension +; Copyright (C) 2007-2018 Jonathan M. Cameron, All rights reserved. +; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL +; Note : All ini files need to be saved as UTF-8 - No BOM + +; English translation + +PLG_QUICKICON_ATTACHMENTS="Quick Icon - Attachments" +PLG_QUICKICON_ATTACHMENTS_XML_DESCRIPTION="Manage the attachments for articles, categories, and other content types." diff --git a/plugins/quickicon/attachments/language/en-GB/index.html b/plugins/quickicon/attachments/language/en-GB/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/plugins/quickicon/attachments/language/en-GB/index.html @@ -0,0 +1 @@ + diff --git a/plugins/quickicon/attachments/language/index.html b/plugins/quickicon/attachments/language/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/plugins/quickicon/attachments/language/index.html @@ -0,0 +1 @@ + diff --git a/plugins/quickicon/attachments/language/it-IT/index.html b/plugins/quickicon/attachments/language/it-IT/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/plugins/quickicon/attachments/language/it-IT/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/quickicon/attachments/language/it-IT/it-IT.plg_quickicon_attachments.ini b/plugins/quickicon/attachments/language/it-IT/it-IT.plg_quickicon_attachments.ini new file mode 100644 index 00000000..9c026ae3 --- /dev/null +++ b/plugins/quickicon/attachments/language/it-IT/it-IT.plg_quickicon_attachments.ini @@ -0,0 +1,13 @@ +; it-IT.plg_quickicon_attachments.ini +; Attachments for Joomla! extension +; Copyright (C) 2007-2013 Jonathan M. Cameron, All rights reserved. +; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL +; Note : All ini files need to be saved as UTF-8 - No BOM + +; Italian translation by: Piero Mattirolo (2.0-3.1), Lemminkainen (version 1.3.4) + +PLG_QUICKICON_ATTACHMENTS="Icona rapida - Allegati" +PLG_QUICKICON_ATTACHMENTS_GROUP_DESC="Il gruppo di questo plugin (questo valore è confrontato con il valore del gruppo utilizzato nei moduli Icone rapide per inserire icone" +PLG_QUICKICON_ATTACHMENTS_GROUP_LABEL="Gruppo" +PLG_QUICKICON_ATTACHMENTS_ICON="Gestione Allegati" +PLG_QUICKICON_ATTACHMENTS_XML_DESCRIPTION="Gestisce allegati per articoli, categorie e altri tipi di contenuti" diff --git a/plugins/quickicon/attachments/language/it-IT/it-IT.plg_quickicon_attachments.sys.ini b/plugins/quickicon/attachments/language/it-IT/it-IT.plg_quickicon_attachments.sys.ini new file mode 100644 index 00000000..b2e33d1e --- /dev/null +++ b/plugins/quickicon/attachments/language/it-IT/it-IT.plg_quickicon_attachments.sys.ini @@ -0,0 +1,10 @@ +; it-IT.plg_quickicon_attachments.sys.ini +; Attachments for Joomla! extension +; Copyright (C) 2007-2013 Jonathan M. Cameron, All rights reserved. +; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL +; Note : All ini files need to be saved as UTF-8 - No BOM + +; Italian translation by: Piero Mattirolo (2.0-3.1), Lemminkainen (version 1.3.4) + +PLG_QUICKICON_ATTACHMENTS="Icona rapida - Allegati" +PLG_QUICKICON_ATTACHMENTS_XML_DESCRIPTION="Gestisce allegati per articoli, categorie e altri tipi di contenuti" diff --git a/plugins/search/attachments/attachments.php b/plugins/search/attachments/attachments.php new file mode 100644 index 00000000..19816a50 --- /dev/null +++ b/plugins/search/attachments/attachments.php @@ -0,0 +1,286 @@ +loadLanguage(); + } + + + /** + * @return array An array of search areas + */ + public function onContentSearchAreas() + { + static $areas = array( + 'attachments' => 'ATTACH_ATTACHMENTS' + ); + return $areas; + } + + + /** + * Attachments Search method + * + * The sql must return the following fields that are + * used in a common display routine: href, title, section, created, text, + * browsernav + * @param string Target search string + * @param string mathcing option, exact|any|all + * @param string ordering option, newest|oldest|popular|alpha|category + * @param mixed An array if restricted to areas, null if search all + */ + public function onContentSearch($text, $phrase='', $ordering='', $areas=null) + { + $user = JFactory::getUser(); + + // Exit if the search does not include attachments + if (is_array($areas)) { + if (!array_intersect( $areas, array_keys( $this->onContentSearchAreas()))) { + return array(); + } + } + + // Make sure we have something to search for + $text = JString::trim( $text ); + if ($text == '') { + return array(); + } + + // load search limit from plugin params + $limit = $this->params->def('search_limit', 50); + + // Get the component parameters + jimport('joomla.application.component.helper'); + $attachParams = JComponentHelper::getParams('com_attachments'); + $secure = $attachParams->get('secure', false); + $user_field_1 = false; + if ( JString::strlen($attachParams->get('user_field_1_name', '')) > 0 ) { + $user_field_1 = true; + $user_field_1_name = $attachParams->get('user_field_1_name'); + } + $user_field_2 = false; + if ( JString::strlen($attachParams->get('user_field_2_name', '')) > 0 ) { + $user_field_2 = true; + $user_field_2_name = $attachParams->get('user_field_2_name'); + } + $user_field_3 = false; + if ( JString::strlen($attachParams->get('user_field_3_name', '')) > 0 ) { + $user_field_3 = true; + $user_field_3_name = $attachParams->get('user_field_3_name'); + } + + $wheres = array(); + + // Create the search query + $db = JFactory::getDBO(); + + switch ($phrase) { + + case 'exact': + $text = $db->quote( '%'.$db->escape( $text, true ).'%', false ); + $user_fields_sql = ''; + if ( $user_field_1 ) + $user_fields_sql .= " OR (LOWER(a.user_field_1) LIKE $text)"; + if ( $user_field_2 ) + $user_fields_sql .= " OR (LOWER(a.user_field_2) LIKE $text)"; + if ( $user_field_3 ) + $user_fields_sql .= " OR (LOWER(a.user_field_3) LIKE $text)"; + + $where = "((LOWER(a.filename) LIKE $text)" . + " OR (LOWER(a.display_name) LIKE $text)" . + $user_fields_sql . + " OR (LOWER(a.description) LIKE $text))"; + break; + + default: + $words = explode( ' ', $text ); + $wheres = array(); + foreach ($words as $word) { + $word = $db->quote( '%'.$db->escape( $word, true ).'%', false ); + $wheres2 = array(); + $wheres2[] = "LOWER(a.filename) LIKE $word"; + $wheres2[] = "LOWER(a.display_name) LIKE $word"; + $wheres2[] = "LOWER(a.url) LIKE $word"; + if ( $user_field_1 ) + $wheres2[] = "LOWER(a.user_field_1) LIKE $word"; + if ( $user_field_2 ) + $wheres2[] = "LOWER(a.user_field_2) LIKE $word"; + if ( $user_field_3 ) + $wheres2[] = "LOWER(a.user_field_3) LIKE $word"; + $wheres2[] = "LOWER(a.description) LIKE $word"; + $wheres[] = implode( ' OR ', $wheres2 ); + } + $where = '(' . implode( ($phrase == 'all' ? ') AND (' : ') OR ('), $wheres ) . ')'; + break; + } + + // Set up the sorting + switch ( $ordering ) + { + case 'oldest': + $order = 'a.created ASC'; + break; + + case 'newest': + $order = 'a.created DESC'; + break; + + case 'alpha': + default: + $order = 'a.filename DESC'; + } + + // Load the permissions functions + $user = JFactory::getUser(); + $user_levels = implode(',', array_unique($user->getAuthorisedViewLevels())); + + // Construct and execute the query + $query = $db->getQuery(true); + $query->select('*')->from('#__attachments AS a'); + $query->where("( $where ) AND a.state = 1"); + if ( !$user->authorise('core.admin') ) { + $query->where('a.access in ('.$user_levels.')'); + } + $query->order($order); + $db->setQuery( $query, 0, $limit ); + $attachments = $db->loadObjectList(); + + $count = count( $attachments ); + + // See if we are done + $results = Array(); + if ( $count <= 0 ) { + return $results; + } + + // Prepare to get parent info + JPluginHelper::importPlugin('attachments'); + $apm = getAttachmentsPluginManager(); + + // Add the result data to the results of the search + $k = 0; + for ( $i = 0; $i < $count; $i++ ) { + + $attachment = $attachments[$i]; + + // Get the parent handler + $parent_type = $attachment->parent_type; + $parent_entity = $attachment->parent_entity; + if ( !$apm->attachmentsPluginInstalled($parent_type) ) { + // Exit if there is no Attachments plugin to handle this parent_type, ignore it + continue; + } + $parent = $apm->getAttachmentsPlugin($parent_type); + + // Ignore the attachment if the user may not see the parent + if ( ! $parent->userMayViewParent($attachment->parent_id, $parent_entity) ) { + continue; + } + + // Ignore the attachment if the parent is not published + if ( ! $parent->isParentPublished($attachment->parent_id, $parent_entity) ) { + continue; + } + + // Do not add the attachment if the user may not access it + if ( !$parent->userMayAccessAttachment($attachment)) { + continue; + } + + // Add the parent title + $attachment->parent_title = $parent->getTitle($attachment->parent_id, $parent_entity); + + // Construct the download URL if necessary + if ( $secure && $attachment->uri_type == 'file' ) { + $attachment->href = + JRoute::_("index.php?option=com_attachments&task=download&id=" . (int)$attachment->id); + } + else { + $attachment->href = $attachment->url; + } + if ( $attachment->display_name && (JString::strlen($attachment->display_name) > 0) ) { + $attachment->title = JString::str_ireplace('·', '.', $attachment->display_name); + } + else { + if ( $attachment->uri_type == 'file' ) { + $attachment->title = $attachment->filename; + } + else { + $attachment->title = $attachment->url; + } + } + + // Set the text to the string containing the search target + if ( JString::strlen($attachment->display_name) > 0 ) { + $text = $attachment->display_name . + " (" . JText::_('ATTACH_FILENAME_COLON') . " " . $attachment->filename . ") "; + } + else { + $text = JText::_('ATTACH_FILENAME_COLON') . " " . $attachment->filename; + } + + if ( JString::strlen($attachment->description) > 0 ) { + $text .= " | " . JText::_('ATTACH_DESCRIPTION_COLON') . stripslashes($attachment->description); + } + + if ( $user_field_1 && (JString::strlen($attachment->user_field_1) > 0) ) { + $text .= " | " . $user_field_1_name . ": " . stripslashes($attachment->user_field_1); + } + if ( $user_field_2 && (JString::strlen($attachment->user_field_2) > 0) ) { + $text .= " | " . $user_field_2_name . ": " . stripslashes($attachment->user_field_2); + } + if ( $user_field_3 && (JString::strlen($attachment->user_field_3) > 0) ) { + $text .= " | " . $user_field_3_name . ": " . stripslashes($attachment->user_field_3); + } + $attachment->text = $text; + $attachment->browsernav = 2; + + $parent_entity_name = JText::_('ATTACH_' . $parent_entity); + $attachment->parent_entity_name = $parent_entity_name; + + $parent_title = JText::_($parent->getTitle($attachment->parent_id, $parent_entity)); + + $attachment->section = JText::sprintf('ATTACH_ATTACHED_TO_PARENT_S_TITLE_S', + $parent_entity_name, $parent_title); + + $results[$k] = $attachment; + $k++; + } + + return $results; + } + +} diff --git a/plugins/search/attachments/attachments.xml b/plugins/search/attachments/attachments.xml new file mode 100644 index 00000000..3121abc2 --- /dev/null +++ b/plugins/search/attachments/attachments.xml @@ -0,0 +1,28 @@ + + + plg_search_attachments + 3.2.6 + March 26, 2018 + Jonathan M. Cameron + jmcameron@jmcameron.net + http://joomlacode.org/gf/project/attachments/ + (C) 2007-2018 Jonathan M. Cameron. All rights reserved. + http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL + ATTACH_ATTACHMENTS_SEARCH_PLUGIN_DESCRIPTION + + + attachments.php + index.html + language + + + + +
+ +
+
+
+ +
diff --git a/plugins/search/attachments/index.html b/plugins/search/attachments/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/plugins/search/attachments/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/search/attachments/language/en-GB/en-GB.plg_search_attachments.ini b/plugins/search/attachments/language/en-GB/en-GB.plg_search_attachments.ini new file mode 100644 index 00000000..17fc43f0 --- /dev/null +++ b/plugins/search/attachments/language/en-GB/en-GB.plg_search_attachments.ini @@ -0,0 +1,15 @@ +; en-GB.plg_search_attachments.ini +; Attachments for Joomla! extension +; Copyright (C) 2007-2018 Jonathan M. Cameron, All rights reserved. +; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL +; Note : All ini files need to be saved as UTF-8 - No BOM + +; English translation + +ATTACH_ATTACHED_TO_PARENT_S_TITLE_S="Attached to %s: %s" +ATTACH_ATTACHMENTS="Attachments" +ATTACH_ATTACHMENTS_SEARCH_PLUGIN_DESCRIPTION="The attachments search plugin enables searching all attachment filenames/URLs and descriptions." +ATTACH_DESCRIPTION_COLON="Description:" +ATTACH_FILENAME_COLON="Filename:" +ATTACH_SEARCH_LIMIT="Search limit" +ATTACH_SEARCH_LIMIT_DESCRIPTION="Number of Search items to return" diff --git a/plugins/search/attachments/language/en-GB/en-GB.plg_search_attachments.sys.ini b/plugins/search/attachments/language/en-GB/en-GB.plg_search_attachments.sys.ini new file mode 100644 index 00000000..143d2db5 --- /dev/null +++ b/plugins/search/attachments/language/en-GB/en-GB.plg_search_attachments.sys.ini @@ -0,0 +1,10 @@ +; en-GB.plg_search_attachments.sys.sys.ini +; Attachments for Joomla! extension +; Copyright (C) 2007-2018 Jonathan M. Cameron, All rights reserved. +; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL +; Note : All ini files need to be saved as UTF-8 - No BOM + +; English translation + +ATTACH_ATTACHMENTS_SEARCH_PLUGIN_DESCRIPTION="The attachments search plugin enables searching all attachment filenames/URLs and descriptions." +PLG_SEARCH_ATTACHMENTS="Search - Attachments" diff --git a/plugins/search/attachments/language/en-GB/index.html b/plugins/search/attachments/language/en-GB/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/plugins/search/attachments/language/en-GB/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/search/attachments/language/index.html b/plugins/search/attachments/language/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/plugins/search/attachments/language/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/search/attachments/language/it-IT/index.html b/plugins/search/attachments/language/it-IT/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/plugins/search/attachments/language/it-IT/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/search/attachments/language/it-IT/it-IT.plg_search_attachments.ini b/plugins/search/attachments/language/it-IT/it-IT.plg_search_attachments.ini new file mode 100644 index 00000000..a5e40d54 --- /dev/null +++ b/plugins/search/attachments/language/it-IT/it-IT.plg_search_attachments.ini @@ -0,0 +1,15 @@ +; it-IT.plg_search_attachments.ini +; Attachments for Joomla! extension +; Copyright (C) 2007-2013 Jonathan M. Cameron, All rights reserved. +; License GNU GPL 3: http://www.gnu.org/licenses/gpl-3.0.html +; Note : All ini files need to be saved as UTF-8 - No BOM + +; Italian translation by: Piero Mattirolo (2.0, 3.0), Lemminkainen (version 1.3.4) + +ATTACH_ATTACHED_TO_PARENT_S_TITLE_S="Allegato a %s: %s" +ATTACH_ATTACHMENTS="Allegati" +ATTACH_ATTACHMENTS_SEARCH_PLUGIN_DESCRIPTION="Questo plugin consente di effettuare ricerche, comprendenti nomi di file/URL e descrizioni." +ATTACH_DESCRIPTION_COLON="Descrizione:" +ATTACH_FILENAME_COLON="Nome del File:" +ATTACH_SEARCH_LIMIT="Limita la ricerca" +ATTACH_SEARCH_LIMIT_DESCRIPTION="Numero di elementi da visualizzare" diff --git a/plugins/search/attachments/language/it-IT/it-IT.plg_search_attachments.sys.ini b/plugins/search/attachments/language/it-IT/it-IT.plg_search_attachments.sys.ini new file mode 100644 index 00000000..008da60b --- /dev/null +++ b/plugins/search/attachments/language/it-IT/it-IT.plg_search_attachments.sys.ini @@ -0,0 +1,10 @@ +; it-IT.plg_search_attachments.sys.sys.ini +; Attachments for Joomla! extension +; Copyright (C) 2007-2013 Jonathan M. Cameron, All rights reserved. +; License GNU GPL 3: http://www.gnu.org/licenses/gpl-3.0.html +; Note : All ini files need to be saved as UTF-8 - No BOM + +; Italian translation by: Piero Mattirolo (2.0, 3.0), Lemminkainen (version 1.3.4) + +ATTACH_ATTACHMENTS_SEARCH_PLUGIN_DESCRIPTION="Questo plugin consente di effettuare ricerche, comprendenti nomi di file/URL e descrizioni." +PLG_SEARCH_ATTACHMENTS="Cerca - Allegati"