| Current Path : /home/w/u/e/wuectly/www/03cbe/ |
| Current File : /home/w/u/e/wuectly/www/03cbe/com_associations.tar |
css/sidebyside.css 0000604 00000002351 15245531051 0010170 0 ustar 00 /**
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
.sidebyside .outer-panel {
float: left;
width: 50%;
}
.sidebyside #left-panel .inner-panel {
padding: 0 10px 0 0;
}
.sidebyside #right-panel .inner-panel {
padding: 0 0 0 10px;
}
.sidebyside .full-width {
float: none !important;
width: 100% !important;
}
.sidebyside .full-width .inner-panel {
padding: 0 !important;
}
#reference-association, #target-association {
width: 100%;
height: 1500px;
overflow-y: auto;
border: 0 !important;
}
.target-text {
float: left;
width: 30%;
}
/* RTL overrides */
html[dir=rtl] .sidebyside .outer-panel {
float: right;
}
html[dir=rtl] .sidebyside #left-panel .inner-panel {
padding: 0 0 0 10px;
}
html[dir=rtl] .sidebyside #right-panel .inner-panel {
padding: 0 10px 0 0;
}
html[dir=rtl] .sidebyside .full-width .inner-panel {
padding: 0 !important;
}
html[dir=rtl] .target-text {
float: right;
}
/* Responsive layout */
@media (max-width: 767px) {
.sidebyside .outer-panel {
float: none;
width: 100%;
}
.sidebyside #left-panel .inner-panel {
padding: 0;
}
.sidebyside #right-panel .inner-panel {
padding: 0;
}
}
js/sidebyside.js 0000604 00000016221 15245531051 0007641 0 ustar 00 jQuery(document).ready(function(u){u("#toolbar-target").hide(),u("#toolbar-copy").hide(),Joomla.submitbutton=function(t){if("association.cancel"===t)Joomla.submitform(t);else if("copy"===t){Joomla.loadingLayer("show");var e=document.getElementById("target-association").getAttribute("data-language"),a=window.frames["reference-association"].document.getElementById("jform_language");a.removeAttribute("disabled"),a.value=e,window.frames["reference-association"].Joomla.submitbutton(document.getElementById("adminForm").getAttribute("data-associatedview")+".save2copy")}else if("undo-association"===t){var i=document.getElementById("reference-association"),o=document.getElementById("target-association"),n=(i.getAttribute("data-id"),i.getAttribute("data-language").replace(/-/,"_"));o.getAttribute("data-id"),e=o.getAttribute("data-language").replace(/-/,"_");i=u(i).contents(),o=u(o).contents(),i.find("#jform_associations_"+e+"_id").val(""),i.find("#jform_associations_"+e+"_name").val(""),i.find("#jform_associations_"+e+"_chzn").remove(),i.find("#jform_associations_"+e).val("").change().chosen();var s="";u("#jform_itemlanguage option").each(function(){void 0!==(s=u(this).val().split("|")[0])&&(s=s.replace(/-/,"_"),o.find("#jform_associations_"+s+"_id").val(""),o.find("#jform_associations_"+s+"_chzn").remove(),o.find("#jform_associations_"+s).val("").change().chosen())}),o.find("#jform_associations_"+n+"_id").val(""),o.find("#jform_associations_"+n+"_name").val(""),o.find("#jform_associations_"+n+"_chzn").remove(),o.find("#jform_associations_"+n).val("").change().chosen();var d=u("#jform_itemlanguage").val(),r=e.replace(/_/,"-");u('#jform_itemlanguage option[value="'+d+'"]').val(r+":0:add"),u("#jform_itemlanguage").val("").change(),u("#jform_itemlanguage").trigger("liszt:updated"),Joomla.submitbutton("reference")}else u("#"+t+"-association").contents().find("#jform_language").attr("disabled",!1),window.frames[t+"-association"].Joomla.submitbutton(document.getElementById("adminForm").getAttribute("data-associatedview")+".apply");return!1},Joomla.loadingLayer("load"),u(document).on("click","#toogle-left-panel",function(){var t=this.getAttribute("data-hide-reference"),e=this.getAttribute("data-show-reference");u(this).text()===t?u(this).text(e):u(this).text(t),u("#left-panel").toggle(),u("#right-panel").toggleClass("full-width")}),u(document).on("change","#jform_itemlanguage",function(){var t=document.getElementById("target-association"),e=u(this).val();""!==e&&void 0!==e?(t.setAttribute("data-action",e.split(":")[2]),t.setAttribute("data-id",e.split(":")[1]),t.setAttribute("data-language",e.split(":")[0]),Joomla.loadingLayer("show"),t.src=t.getAttribute("data-editurl")+"&task="+t.getAttribute("data-item")+"."+t.getAttribute("data-action")+"&id="+t.getAttribute("data-id")):(u("#toolbar-target").hide(),u("#toolbar-copy").hide(),u("#select-change").addClass("hidden"),u("#remove-assoc").addClass("hidden"),t.setAttribute("data-action",""),t.setAttribute("data-id","0"),t.setAttribute("data-language",""),t.src="")}),u("#reference-association").on("load",function(){var t=Joomla.getOptions("targetSrc",!1);if(t)return t=t.split("&").join("&"),document.getElementById("target-association").setAttribute("src",t),void Joomla.loadOptions({targetSrc:!1});if(document.getElementById("target-association").setAttribute("src",document.getElementById("target-association").getAttribute("src")),u(this).contents().find("#jform_id").val()!==this.getAttribute("data-id")){var e=document.getElementById("target-association");e.src=e.getAttribute("data-editurl")+"&task="+e.getAttribute("data-item")+".edit&id="+u(this).contents().find("#jform_id").val(),this.src=this.getAttribute("data-editurl")+"&task="+this.getAttribute("data-item")+".edit&id="+this.getAttribute("data-id")}var a=u(this).contents();a.find("#jform_language_chzn").remove(),a.find("#jform_language").attr("disabled",!0).chosen(),a.find("#associations").find(".btn").remove();var i="";u("#jform_itemlanguage option").each(function(){void 0!==(i=u(this).val().split(":"))[0]&&(langAssociation=i[0].replace(/-/,"_"),""==a.find("#jform_associations_"+langAssociation+"_id").val()&&a.find("#jform_associations_"+langAssociation+"_name").val(document.getElementById("reference-association").getAttribute("data-no-assoc")))}),Joomla.loadingLayer("hide")}),u("#target-association").on("load",function(){if(""!=this.getAttribute("src")){u("#toolbar-target").show(),u("#toolbar-copy").show(),u("#select-change").removeClass("hidden");var t=this.getAttribute("data-language"),e=this.getAttribute("data-id"),a=u(this).contents().find("#jform_id").val()||"0";if(u(this).contents().find('a[href="#associations"]').parent().find(".btn").remove(),u(this).contents().find("#associations").find(".btn").remove(),u(this).contents().find("#associations").hasClass("active")&&(u(this).contents().find('a[href="#associations"]').parent().removeClass("active"),u(this).contents().find("#associations").removeClass("active"),u(this).contents().find(".nav-tabs").find("li").first().addClass("active"),u(this).contents().find(".tab-content").find(".tab-pane").first().addClass("active")),u(this).contents().find("#jform_language_chzn").remove(),u(this).contents().find("#jform_language").val(t).change().attr("disabled",!0).chosen(),"0"==a)document.getElementById("select-change-text").innerHTML=document.getElementById("select-change").getAttribute("data-select");else{document.getElementById("select-change-text").innerHTML=document.getElementById("select-change").getAttribute("data-change"),u("#remove-assoc").removeClass("hidden"),u("#toolbar-copy").hide();var i=document.getElementById("target-id").value,o=""==i?a:i+","+a;document.getElementById("target-id").value=o,a!=e&&(u('#jform_itemlanguage option[value^="'+t+":"+e+':add"]').val(t+":"+a+":edit"),this.setAttribute("data-id",a),this.setAttribute("data-action","edit"));var n=document.getElementById("reference-association"),s=t.replace(/-/,"_"),d=n.getAttribute("data-title"),r=u(this).contents().find("#jform_"+d).val();u(n).contents().find("#jform_associations_"+s+"_id").val(a),u(n).contents().find("#jform_associations_"+s+"_name").val(r),u(n).contents().find("#jform_associations_"+s+"_chzn").remove(),u(n).contents().find("#jform_associations_"+s).append('<option value="'+a+'">'+r+"</option>"),u(n).contents().find("#jform_associations_"+s).val(a).change().chosen()}var c,l=(n=document.getElementById("reference-association")).getAttribute("data-id");s=n.getAttribute("data-language").replace(/-/,"_"),(c=document.getElementById("target-association")).getAttribute("data-title"),r=n.getAttribute("data-title-value");(c=u(this).contents()).find("#jform_associations_"+s+"_id").val(l),c.find("#jform_associations_"+s+"_name").val(r),c.find("#jform_associations_"+s+"_chzn").remove();var m,g,f=c.find("#jform_associations_"+s);f.append('<option value="'+l+'">'+r+"</option>"),f.val(l).change().chosen(),u("#jform_itemlanguage option").each(function(){void 0!==(m=u(this).val().split(":"))[1]&&"0"!==m[1]&&(g=m[0].replace(/-/,"_"),c.find("#jform_associations_"+g+"_id").val(m[1]),c.find("#jform_associations_"+g+"_chzn").remove(),(f=c.find("#jform_associations_"+g)).append('<option value="'+m[1]+'"></option>'),f.val(m[1]).change().chosen())}),Joomla.loadingLayer("hide")}})});
js/sidebyside-uncompressed.js 0000604 00000032066 15245531051 0012353 0 ustar 00 /**
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
jQuery(document).ready(function($) {
$('#toolbar-target').hide();
$('#toolbar-copy').hide();
// Save button actions, replacing the default Joomla.submitbutton() with custom function.
Joomla.submitbutton = function(task)
{
// Using close button, normal joomla submit.
if (task === 'association.cancel')
{
Joomla.submitform(task);
}
else if(task === 'copy')
{
Joomla.loadingLayer('show');
var targetLang = document.getElementById('target-association').getAttribute('data-language'),
referlangInput = window.frames['reference-association'].document.getElementById('jform_language');
// Set target language, to get correct content language in the copy
referlangInput.removeAttribute('disabled');
referlangInput.value = targetLang;
window.frames['reference-association'].Joomla.submitbutton(document.getElementById('adminForm').getAttribute('data-associatedview') + '.save2copy');
}
// Undo association
else if (task === 'undo-association')
{
var reference = document.getElementById('reference-association');
var target = document.getElementById('target-association');
var referenceId = reference.getAttribute('data-id');
var referenceLang = reference.getAttribute('data-language').replace(/-/,'_');
var targetId = target.getAttribute('data-id');
var targetLang = target.getAttribute('data-language').replace(/-/,'_');
reference = $(reference).contents();
target = $(target).contents();
// Remove it on the reference
// - For modal association selectors.
reference.find('#jform_associations_' + targetLang + '_id').val('');
reference.find('#jform_associations_' + targetLang + '_name').val('');
// - For chosen association selectors (menus).
reference.find('#jform_associations_' + targetLang + '_chzn').remove();
reference.find('#jform_associations_' + targetLang).val('').change().chosen();
var lang = '';
// Remove it on the target
$('#jform_itemlanguage option').each(function()
{
lang = $(this).val().split('|')[0];
if (typeof lang !== 'undefined')
{
lang = lang.replace(/-/,'_');
// - For modal association selectors.
target.find('#jform_associations_' + lang + '_id').val('');
// - For chosen association selectors (menus).
target.find('#jform_associations_' + lang + '_chzn').remove();
target.find('#jform_associations_' + lang).val('').change().chosen();
}
});
// Same as above but reference language is not in the selector
// - For modal association selectors.
target.find('#jform_associations_' + referenceLang + '_id').val('');
target.find('#jform_associations_' + referenceLang + '_name').val('');
// - For chosen association selectors (menus).
target.find('#jform_associations_' + referenceLang + '_chzn').remove();
target.find('#jform_associations_' + referenceLang).val('').change().chosen();
// Reset switcher after removing association
var currentSwitcher = $('#jform_itemlanguage').val();
var currentLang = targetLang.replace(/_/,'-');
$('#jform_itemlanguage option[value=\"' + currentSwitcher + '\"]').val(currentLang + ':0:add');
$('#jform_itemlanguage').val('').change();
$('#jform_itemlanguage').trigger('liszt:updated');
// Save one of the items to confirm action
Joomla.submitbutton('reference');
}
// Saving target or reference, send the save action to the target/reference iframe.
else
{
// We need to re-enable the language field to save.
$('#' + task + '-association').contents().find('#jform_language').attr('disabled', false);
window.frames[task + '-association'].Joomla.submitbutton(document.getElementById('adminForm').getAttribute('data-associatedview') + '.apply');
}
return false;
};
// Preload Joomla loading layer.
Joomla.loadingLayer('load');
// Attach behaviour to toggle button.
$(document).on('click', '#toogle-left-panel', function()
{
var referenceHide = this.getAttribute('data-hide-reference');
var referenceShow = this.getAttribute('data-show-reference');
if ($(this).text() === referenceHide)
{
$(this).text(referenceShow);
}
else
{
$(this).text(referenceHide);
}
$('#left-panel').toggle();
$('#right-panel').toggleClass('full-width');
});
// Attach behaviour to language selector change event.
$(document).on('change', '#jform_itemlanguage', function() {
var target = document.getElementById('target-association');
var selected = $(this).val();
// Populate the data attributes and load the the edit page in target frame.
if (selected !== '' && typeof selected !== 'undefined')
{
target.setAttribute('data-action', selected.split(':')[2]);
target.setAttribute('data-id', selected.split(':')[1]);
target.setAttribute('data-language', selected.split(':')[0]);
// Iframe load start, show Joomla loading layer.
Joomla.loadingLayer('show');
// Load the target frame.
target.src = target.getAttribute('data-editurl') + '&task=' + target.getAttribute('data-item') + '.' + target.getAttribute('data-action') + '&id=' + target.getAttribute('data-id');
}
// Reset the data attributes and no item to load.
else
{
$('#toolbar-target').hide();
$('#toolbar-copy').hide();
$('#select-change').addClass("hidden");
$('#remove-assoc').addClass("hidden");
target.setAttribute('data-action', '');
target.setAttribute('data-id', '0');
target.setAttribute('data-language', '');
target.src = '';
}
});
// Attach behaviour to reference frame load event.
$('#reference-association').on('load', function() {
// Waiting until the reference has loaded before loading the target to avoid race conditions
var targetURL = Joomla.getOptions('targetSrc', false);
if (targetURL)
{
targetURL = targetURL.split('&').join('&');
document.getElementById('target-association').setAttribute('src', targetURL);
Joomla.loadOptions({'targetSrc': false});
return;
}
// Load Target Pane AFTER reference pane has loaded to prevent session conflict with checkout
document.getElementById('target-association').setAttribute('src', document.getElementById('target-association').getAttribute('src'));
// If copy button used
if ($(this).contents().find('#jform_id').val() !== this.getAttribute('data-id'))
{
var target = document.getElementById('target-association');
target.src = target.getAttribute('data-editurl') + '&task=' + target.getAttribute('data-item') + '.edit' + '&id=' + $(this).contents().find('#jform_id').val();
this.src = this.getAttribute('data-editurl') + '&task=' + this.getAttribute('data-item') + '.edit' + '&id=' + this.getAttribute('data-id');
}
var reference = $(this).contents();
// Disable language field.
reference.find('#jform_language_chzn').remove();
reference.find('#jform_language').attr('disabled', true).chosen();
// Remove modal buttons on the reference
reference.find('#associations').find('.btn').remove();
var parse = '';
$('#jform_itemlanguage option').each(function()
{
parse = $(this).val().split(':');
if (typeof parse[0] !== 'undefined')
{
// - For modal association selectors.
langAssociation = parse[0].replace(/-/,'_');
if (reference.find('#jform_associations_' + langAssociation + '_id').val() == '')
{
reference.find('#jform_associations_' + langAssociation + '_name')
.val(document.getElementById('reference-association').getAttribute('data-no-assoc'));
}
}
});
// Iframe load finished, hide Joomla loading layer.
Joomla.loadingLayer('hide');
});
// Attach behaviour to target frame load event.
$('#target-association').on('load', function() {
// We need to check if we are not loading a blank iframe.
if (this.getAttribute('src') != '')
{
$('#toolbar-target').show();
$('#toolbar-copy').show();
$('#select-change').removeClass("hidden");
var targetLanguage = this.getAttribute('data-language');
var targetId = this.getAttribute('data-id');
var targetLoadedId = $(this).contents().find('#jform_id').val() || '0';
// Remove modal buttons on the target
$(this).contents().find('a[href=\"#associations\"]').parent().find('.btn').remove();
$(this).contents().find('#associations').find('.btn').remove();
// Always show General tab first if associations tab is selected on the reference
if ($(this).contents().find('#associations').hasClass('active'))
{
$(this).contents().find('a[href=\"#associations\"]').parent().removeClass('active');
$(this).contents().find('#associations').removeClass('active');
$(this).contents().find('.nav-tabs').find('li').first().addClass('active');
$(this).contents().find('.tab-content').find('.tab-pane').first().addClass('active');
}
// Update language field with the selected language and them disable it.
$(this).contents().find('#jform_language_chzn').remove();
$(this).contents().find('#jform_language').val(targetLanguage).change().attr('disabled', true).chosen();
// If we are creating a new association (before save) we need to add the new association.
if (targetLoadedId == '0')
{
document.getElementById('select-change-text').innerHTML = document.getElementById('select-change').getAttribute('data-select');
}
// If we are editing an association.
else
{
// Show change language button
document.getElementById('select-change-text').innerHTML = document.getElementById('select-change').getAttribute('data-change');
$('#remove-assoc').removeClass("hidden");
$('#toolbar-copy').hide();
// Add the id to list of items to check in on close.
var currentIdList = document.getElementById('target-id').value;
var updatedList = currentIdList == '' ? targetLoadedId : currentIdList + ',' + targetLoadedId;
document.getElementById('target-id').value = updatedList;
// If we created a new association (after save).
if (targetLoadedId != targetId)
{
// Refresh the language selector with the new id (used after save).
$('#jform_itemlanguage option[value^=\"' + targetLanguage + ':' + targetId + ':add\"]').val(targetLanguage + ':' + targetLoadedId + ':edit');
// Update main frame data-id attribute (used after save).
this.setAttribute('data-id', targetLoadedId);
this.setAttribute('data-action', 'edit');
}
// Update the reference item associations tab.
var reference = document.getElementById('reference-association');
var languageCode = targetLanguage.replace(/-/, '_');
var referenceTitle = reference.getAttribute('data-title');
var title = $(this).contents().find('#jform_' + referenceTitle).val();
// - For modal association selectors.
$(reference).contents().find('#jform_associations_' + languageCode + '_id').val(targetLoadedId);
$(reference).contents().find('#jform_associations_' + languageCode + '_name').val(title);
// - For chosen association selectors (menus).
$(reference).contents().find('#jform_associations_' + languageCode + '_chzn').remove();
$(reference).contents().find('#jform_associations_' + languageCode).append('<option value=\"'+ targetLoadedId + '\">' + title + '</option>');
$(reference).contents().find('#jform_associations_' + languageCode).val(targetLoadedId).change().chosen();
}
// Update the target item associations tab.
var reference = document.getElementById('reference-association');
var referenceId = reference.getAttribute('data-id');
var languageCode = reference.getAttribute('data-language').replace(/-/, '_');
var target = document.getElementById('target-association');
var targetTitle = target.getAttribute('data-title');
var title = reference.getAttribute('data-title-value');
var target = $(this).contents();
// - For modal association selectors.
target.find('#jform_associations_' + languageCode + '_id').val(referenceId);
target.find('#jform_associations_' + languageCode + '_name').val(title);
// - For chosen association selectors (menus).
target.find('#jform_associations_' + languageCode + '_chzn').remove();
var chznField = target.find('#jform_associations_' + languageCode);
chznField.append('<option value=\"'+ referenceId + '\">' + title + '</option>');
chznField.val(referenceId).change().chosen();
var parse, langAssociation;
$('#jform_itemlanguage option').each(function()
{
parse = $(this).val().split(':');
if (typeof parse[1] !== 'undefined' && parse[1] !== '0')
{
// - For modal association selectors.
langAssociation = parse[0].replace(/-/,'_');
target.find('#jform_associations_' + langAssociation + '_id').val(parse[1]);
// - For chosen association selectors (menus).
target.find('#jform_associations_' + langAssociation + '_chzn').remove();
chznField = target.find('#jform_associations_' + langAssociation);
chznField.append('<option value=\"'+ parse[1] + '\"></option>');
chznField.val(parse[1]).change().chosen();
}
});
// Iframe load finished, hide Joomla loading layer.
Joomla.loadingLayer('hide');
}
});
});
helpers/associations.php 0000604 00000041424 15245557232 0011431 0 ustar 00 <?php
/**
* @package Joomla.Administrator
* @subpackage com_associations
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\Registry\Registry;
use Joomla\CMS\Language\LanguageHelper;
/**
* Associations component helper.
*
* @since 3.7.0
*/
class AssociationsHelper extends JHelperContent
{
/**
* Array of Registry objects of extensions
*
* var array $extensionsSupport
*
* @since 3.7.0
*/
public static $extensionsSupport = null;
/**
* List of extensions name with support
*
* var array $supportedExtensionsList
*
* @since 3.7.0
*/
public static $supportedExtensionsList = array();
/**
* Get the associated items for an item
*
* @param string $extensionName The extension name with com_
* @param string $typeName The item type
* @param int $itemId The id of item for which we need the associated items
*
* @return array
*
* @since 3.7.0
*/
public static function getAssociationList($extensionName, $typeName, $itemId)
{
if (!self::hasSupport($extensionName))
{
return array();
}
// Get the extension specific helper method
$helper = self::getExtensionHelper($extensionName);
return $helper->getAssociationList($typeName, $itemId);
}
/**
* Get the the instance of the extension helper class
*
* @param string $extensionName The extension name with com_
*
* @return HelperClass|null
*
* @since 3.7.0
*/
public static function getExtensionHelper($extensionName)
{
if (!self::hasSupport($extensionName))
{
return null;
}
$support = self::$extensionsSupport[$extensionName];
return $support->get('helper');
}
/**
* Get item information
*
* @param string $extensionName The extension name with com_
* @param string $typeName The item type
* @param int $itemId The id of item for which we need the associated items
*
* @return JTable|null
*
* @since 3.7.0
*/
public static function getItem($extensionName, $typeName, $itemId)
{
if (!self::hasSupport($extensionName))
{
return array();
}
// Get the extension specific helper method
$helper = self::getExtensionHelper($extensionName);
return $helper->getItem($typeName, $itemId);
}
/**
* Check if extension supports associations
*
* @param string $extensionName The extension name with com_
*
* @return boolean
*
* @since 3.7.0
*/
public static function hasSupport($extensionName)
{
if (is_null(self::$extensionsSupport))
{
self::getSupportedExtensions();
}
return in_array($extensionName, self::$supportedExtensionsList);
}
/**
* Get the extension specific helper class name
*
* @param string $extensionName The extension name with com_
*
* @return boolean
*
* @since 3.7.0
*/
private static function getExtensionHelperClassName($extensionName)
{
$realName = self::getExtensionRealName($extensionName);
return ucfirst($realName) . 'AssociationsHelper';
}
/**
* Get the real extension name. This means without com_
*
* @param string $extensionName The extension name with com_
*
* @return string
*
* @since 3.7.0
*/
private static function getExtensionRealName($extensionName)
{
return strpos($extensionName, 'com_') === false ? $extensionName : substr($extensionName, 4);
}
/**
* Get the associated language edit links Html.
*
* @param string $extensionName Extension Name
* @param string $typeName ItemType
* @param integer $itemId Item id.
* @param string $itemLanguage Item language code.
* @param boolean $addLink True for adding edit links. False for just text.
* @param boolean $assocLanguages True for showing non associated content languages. False only languages with associations.
*
* @return string The language HTML
*
* @since 3.7.0
*/
public static function getAssociationHtmlList($extensionName, $typeName, $itemId, $itemLanguage, $addLink = true, $assocLanguages = true)
{
// Get the associations list for this item.
$items = self::getAssociationList($extensionName, $typeName, $itemId);
$titleFieldName = self::getTypeFieldName($extensionName, $typeName, 'title');
// Get all content languages.
$languages = LanguageHelper::getContentLanguages(array(0, 1));
$canEditReference = self::allowEdit($extensionName, $typeName, $itemId);
$canCreate = self::allowAdd($extensionName, $typeName);
// Create associated items list.
foreach ($languages as $langCode => $language)
{
// Don't do for the reference language.
if ($langCode == $itemLanguage)
{
continue;
}
// Don't show languages with associations, if we don't want to show them.
if ($assocLanguages && isset($items[$langCode]))
{
unset($items[$langCode]);
continue;
}
// Don't show languages without associations, if we don't want to show them.
if (!$assocLanguages && !isset($items[$langCode]))
{
continue;
}
// Get html parameters.
if (isset($items[$langCode]))
{
$title = $items[$langCode][$titleFieldName];
$additional = '';
if (isset($items[$langCode]['catid']))
{
$db = JFactory::getDbo();
// Get the category name
$query = $db->getQuery(true)
->select($db->quoteName('title'))
->from($db->quoteName('#__categories'))
->where($db->quoteName('id') . ' = ' . $db->quote($items[$langCode]['catid']));
$db->setQuery($query);
$category_title = $db->loadResult();
$additional = '<strong>' . JText::sprintf('JCATEGORY_SPRINTF', $category_title) . '</strong> <br />';
}
elseif (isset($items[$langCode]['menutype']))
{
$db = JFactory::getDbo();
// Get the menutype name
$query = $db->getQuery(true)
->select($db->quoteName('title'))
->from($db->quoteName('#__menu_types'))
->where($db->quoteName('menutype') . ' = ' . $db->quote($items[$langCode]['menutype']));
$db->setQuery($query);
$menutype_title = $db->loadResult();
$additional = '<strong>' . JText::sprintf('COM_MENUS_MENU_SPRINTF', $menutype_title) . '</strong><br />';
}
$labelClass = '';
$target = $langCode . ':' . $items[$langCode]['id'] . ':edit';
$allow = $canEditReference
&& self::allowEdit($extensionName, $typeName, $items[$langCode]['id'])
&& self::canCheckinItem($extensionName, $typeName, $items[$langCode]['id']);
$additional .= $addLink && $allow ? JText::_('COM_ASSOCIATIONS_EDIT_ASSOCIATION') : '';
}
else
{
$items[$langCode] = array();
$title = JText::_('COM_ASSOCIATIONS_NO_ASSOCIATION');
$additional = $addLink ? JText::_('COM_ASSOCIATIONS_ADD_NEW_ASSOCIATION') : '';
$labelClass = 'label-warning';
$target = $langCode . ':0:add';
$allow = $canCreate;
}
// Generate item Html.
$options = array(
'option' => 'com_associations',
'view' => 'association',
'layout' => 'edit',
'itemtype' => $extensionName . '.' . $typeName,
'task' => 'association.edit',
'id' => $itemId,
'target' => $target,
);
$url = JRoute::_('index.php?' . http_build_query($options));
$url = $allow && $addLink ? $url : '';
$text = strtoupper($language->sef);
$tooltip = htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '<br /><br />' . $additional;
$classes = 'hasPopover label ' . $labelClass . ' label-' . $language->sef;
$items[$langCode]['link'] = '<a href="' . $url . '" title="' . $language->title . '" class="' . $classes
. '" data-content="' . $tooltip . '" data-placement="top">'
. $text . '</a>';
}
JHtml::_('bootstrap.popover');
return JLayoutHelper::render('joomla.content.associations', $items);
}
/**
* Get all extensions with associations support.
*
* @return array The extensions.
*
* @since 3.7.0
*/
public static function getSupportedExtensions()
{
if (!is_null(self::$extensionsSupport))
{
return self::$extensionsSupport;
}
self::$extensionsSupport = array();
$extensions = self::getEnabledExtensions();
foreach ($extensions as $extension)
{
$support = self::getSupportedExtension($extension->element);
if ($support->get('associationssupport') === true)
{
self::$supportedExtensionsList[] = $extension->element;
}
self::$extensionsSupport[$extension->element] = $support;
}
return self::$extensionsSupport;
}
/**
* Get item context based on the item key.
*
* @param string $extensionName The extension identifier.
*
* @return Joomla\Registry\Registry The item properties.
*
* @since 3.7.0
*/
public static function getSupportedExtension($extensionName)
{
$result = new Registry;
$result->def('component', $extensionName);
$result->def('associationssupport', false);
$result->def('helper', null);
// Check if associations helper exists
if (!file_exists(JPATH_ADMINISTRATOR . '/components/' . $extensionName . '/helpers/associations.php'))
{
return $result;
}
require_once JPATH_ADMINISTRATOR . '/components/' . $extensionName . '/helpers/associations.php';
$componentAssociationsHelperClassName = self::getExtensionHelperClassName($extensionName);
if (!class_exists($componentAssociationsHelperClassName, false))
{
return $result;
}
// Create an instance of the helper class
$helper = new $componentAssociationsHelperClassName;
$result->set('helper', $helper);
if ($helper->hasAssociationsSupport() === false)
{
return $result;
}
$result->set('associationssupport', true);
// Get the translated titles.
$languagePath = JPATH_ADMINISTRATOR . '/components/' . $extensionName;
$lang = JFactory::getLanguage();
$lang->load($extensionName . '.sys', JPATH_ADMINISTRATOR);
$lang->load($extensionName . '.sys', $languagePath);
$lang->load($extensionName, JPATH_ADMINISTRATOR);
$lang->load($extensionName, $languagePath);
$result->def('title', JText::_(strtoupper($extensionName)));
// Get the supported types
$types = $helper->getItemTypes();
$rTypes = array();
foreach ($types as $typeName)
{
$details = $helper->getType($typeName);
$context = 'component';
$title = $helper->getTypeTitle($typeName);
$languageKey = $typeName;
if ($typeName === 'category')
{
$languageKey = strtoupper($extensionName) . '_CATEGORIES';
$context = 'category';
}
if ($lang->hasKey(strtoupper($extensionName . '_' . $title . 'S')))
{
$languageKey = strtoupper($extensionName . '_' . $title . 'S');
}
$title = $lang->hasKey($languageKey) ? JText::_($languageKey) : JText::_('COM_ASSOCIATIONS_ITEMS');
$rType = new Registry;
$rType->def('name', $typeName);
$rType->def('details', $details);
$rType->def('title', $title);
$rType->def('context', $context);
$rTypes[$typeName] = $rType;
}
$result->def('types', $rTypes);
return $result;
}
/**
* Get all installed and enabled extensions
*
* @return mixed
*
* @since 3.7.0
*/
private static function getEnabledExtensions()
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('*')
->from($db->quoteName('#__extensions'))
->where($db->quoteName('type') . ' = ' . $db->quote('component'))
->where($db->quoteName('enabled') . ' = 1');
$db->setQuery($query);
return $db->loadObjectList();
}
/**
* Get all the content languages.
*
* @return array Array of objects all content languages by language code.
*
* @since 3.7.0
*/
public static function getContentLanguages()
{
return LanguageHelper::getContentLanguages(array(0, 1));
}
/**
* Get the associated items for an item
*
* @param string $extensionName The extension name with com_
* @param string $typeName The item type
* @param int $itemId The id of item for which we need the associated items
*
* @return boolean
*
* @since 3.7.0
*/
public static function allowEdit($extensionName, $typeName, $itemId)
{
if (!self::hasSupport($extensionName))
{
return false;
}
// Get the extension specific helper method
$helper = self::getExtensionHelper($extensionName);
if (method_exists($helper, 'allowEdit'))
{
return $helper->allowEdit($typeName, $itemId);
}
return JFactory::getUser()->authorise('core.edit', $extensionName);
}
/**
* Check if user is allowed to create items.
*
* @param string $extensionName The extension name with com_
* @param string $typeName The item type
*
* @return boolean True on allowed.
*
* @since 3.7.0
*/
public static function allowAdd($extensionName, $typeName)
{
if (!self::hasSupport($extensionName))
{
return false;
}
// Get the extension specific helper method
$helper = self::getExtensionHelper($extensionName);
if (method_exists($helper, 'allowAdd'))
{
return $helper->allowAdd($typeName);
}
return JFactory::getUser()->authorise('core.create', $extensionName);
}
/**
* Check if an item is checked out
*
* @param string $extensionName The extension name with com_
* @param string $typeName The item type
* @param int $itemId The id of item for which we need the associated items
*
* @return boolean True if item is checked out.
*
* @since 3.7.0
*/
public static function isCheckoutItem($extensionName, $typeName, $itemId)
{
if (!self::hasSupport($extensionName))
{
return false;
}
if (!self::typeSupportsCheckout($extensionName, $typeName))
{
return false;
}
// Get the extension specific helper method
$helper = self::getExtensionHelper($extensionName);
if (method_exists($helper, 'isCheckoutItem'))
{
return $helper->isCheckoutItem($typeName, $itemId);
}
$item = self::getItem($extensionName, $typeName, $itemId);
$checkedOutFieldName = $helper->getTypeFieldName($typeName, 'checked_out');
return $item->{$checkedOutFieldName} != 0;
}
/**
* Check if user can checkin an item.
*
* @param string $extensionName The extension name with com_
* @param string $typeName The item type
* @param int $itemId The id of item for which we need the associated items
*
* @return boolean True on allowed.
*
* @since 3.7.0
*/
public static function canCheckinItem($extensionName, $typeName, $itemId)
{
if (!self::hasSupport($extensionName))
{
return false;
}
if (!self::typeSupportsCheckout($extensionName, $typeName))
{
return true;
}
// Get the extension specific helper method
$helper = self::getExtensionHelper($extensionName);
if (method_exists($helper, 'canCheckinItem'))
{
return $helper->canCheckinItem($typeName, $itemId);
}
$item = self::getItem($extensionName, $typeName, $itemId);
$checkedOutFieldName = $helper->getTypeFieldName($typeName, 'checked_out');
$userId = JFactory::getUser()->id;
return ($item->{$checkedOutFieldName} == $userId || $item->{$checkedOutFieldName} == 0);
}
/**
* Check if the type supports checkout
*
* @param string $extensionName The extension name with com_
* @param string $typeName The item type
*
* @return boolean True on allowed.
*
* @since 3.7.0
*/
public static function typeSupportsCheckout($extensionName, $typeName)
{
if (!self::hasSupport($extensionName))
{
return false;
}
// Get the extension specific helper method
$helper = self::getExtensionHelper($extensionName);
$support = $helper->getTypeSupport($typeName);
return !empty($support['checkout']);
}
/**
* Get a table field name for a type
*
* @param string $extensionName The extension name with com_
* @param string $typeName The item type
* @param string $fieldName The item type
*
* @return boolean True on allowed.
*
* @since 3.7.0
*/
public static function getTypeFieldName($extensionName, $typeName, $fieldName)
{
if (!self::hasSupport($extensionName))
{
return false;
}
// Get the extension specific helper method
$helper = self::getExtensionHelper($extensionName);
return $helper->getTypeFieldName($typeName, $fieldName);
}
/**
* Gets the language filter system plugin extension id.
*
* @return integer The language filter system plugin extension id.
*
* @since 3.7.2
*/
public static function getLanguagefilterPluginId()
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select($db->quoteName('extension_id'))
->from($db->quoteName('#__extensions'))
->where($db->quoteName('folder') . ' = ' . $db->quote('system'))
->where($db->quoteName('element') . ' = ' . $db->quote('languagefilter'));
$db->setQuery($query);
try
{
$result = (int) $db->loadResult();
}
catch (RuntimeException $e)
{
JError::raiseWarning(500, $e->getMessage());
}
return $result;
}
}
associations.xml 0000604 00000002172 15245557232 0007775 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="3.7" method="upgrade">
<name>com_associations</name>
<author>Joomla! Project</author>
<creationDate>January 2017</creationDate>
<copyright>(C) 2017 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.7.0</version>
<description>COM_ASSOCIATIONS_XML_DESCRIPTION</description>
<administration>
<menu img="class:associations">COM_ASSOCIATIONS</menu>
<files folder="admin">
<filename>access.xml</filename>
<filename>config.xml</filename>
<filename>associations.php</filename>
<filename>controller.php</filename>
<folder>controllers</folder>
<folder>helpers</folder>
<folder>layouts</folder>
<folder>models</folder>
<folder>views</folder>
</files>
<languages folder="admin">
<language tag="en-GB">language/en-GB.com_associations.ini</language>
<language tag="en-GB">language/en-GB.com_associations.sys.ini</language>
</languages>
</administration>
</extension>
associations.php 0000604 00000002352 15245557232 0007764 0 ustar 00 <?php
/**
* @package Joomla.Administrator
* @subpackage com_associations
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
JHtml::_('behavior.tabstate');
if (!JFactory::getUser()->authorise('core.manage', 'com_associations'))
{
throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403);
}
JLoader::register('AssociationsHelper', __DIR__ . '/helpers/associations.php');
// Check if user has permission to access the component item type.
$itemtype = JFactory::getApplication()->input->get('itemtype', '', 'string');
if ($itemtype !== '')
{
list($extensionName, $typeName) = explode('.', $itemtype);
if (!AssociationsHelper::hasSupport($extensionName))
{
throw new Exception(JText::sprintf('COM_ASSOCIATIONS_COMPONENT_NOT_SUPPORTED', JText::_($extensionName)), 404);
}
if (!JFactory::getUser()->authorise('core.manage', $extensionName))
{
throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403);
}
}
$controller = JControllerLegacy::getInstance('Associations');
$controller->execute(JFactory::getApplication()->input->get('task'));
$controller->redirect();
models/association.php 0000604 00000001674 15245557232 0011072 0 ustar 00 <?php
/**
* @package Joomla.Administrator
* @subpackage com_associations
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Methods supporting a list of article records.
*
* @since 3.7.0
*/
class AssociationsModelAssociation extends JModelList
{
/**
* Method to get the record form.
*
* @param array $data Data for the form.
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
*
* @return mixed A JForm object on success, false on failure
*
* @since 3.7.0
*/
public function getForm($data = array(), $loadData = true)
{
// Get the form.
$form = $this->loadForm('com_associations.association', 'association', array('control' => 'jform', 'load_data' => $loadData));
return !empty($form) ? $form : false;
}
}
models/fields/itemlanguage.php 0000604 00000006252 15245557232 0012463 0 ustar 00 <?php
/**
* @package Joomla.Administrator
* @subpackage com_associations
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\Utilities\ArrayHelper;
use Joomla\CMS\Language\LanguageHelper;
JLoader::register('AssociationsHelper', JPATH_ADMINISTRATOR . '/components/com_associations/helpers/associations.php');
JFormHelper::loadFieldClass('list');
/**
* Field listing item languages
*
* @since 3.7.0
*/
class JFormFieldItemLanguage extends JFormFieldList
{
/**
* The form field type.
*
* @var string
* @since 3.7.0
*/
protected $type = 'ItemLanguage';
/**
* Method to get the field options.
*
* @return array The field option objects.
*
* @since 3.7.0
*/
protected function getOptions()
{
$input = JFactory::getApplication()->input;
list($extensionName, $typeName) = explode('.', $input->get('itemtype', '', 'string'));
// Get the extension specific helper method
$helper = AssociationsHelper::getExtensionHelper($extensionName);
$languageField = $helper->getTypeFieldName($typeName, 'language');
$referenceId = $input->get('id', 0, 'int');
$reference = ArrayHelper::fromObject(AssociationsHelper::getItem($extensionName, $typeName, $referenceId));
$referenceLang = $reference[$languageField];
// Get item associations given ID and item type
$associations = AssociationsHelper::getAssociationList($extensionName, $typeName, $referenceId);
// Check if user can create items in this component item type.
$canCreate = AssociationsHelper::allowAdd($extensionName, $typeName);
// Gets existing languages.
$existingLanguages = LanguageHelper::getContentLanguages(array(0, 1));
$options = array();
// Each option has the format "<lang>|<id>", example: "en-GB|1"
foreach ($existingLanguages as $langCode => $language)
{
// If language code is equal to reference language we don't need it.
if ($language->lang_code == $referenceLang)
{
continue;
}
$options[$langCode] = new stdClass;
$options[$langCode]->text = $language->title;
// If association exists in this language.
if (isset($associations[$language->lang_code]))
{
$itemId = (int) $associations[$language->lang_code]['id'];
$options[$langCode]->value = $language->lang_code . ':' . $itemId . ':edit';
// Check if user does have permission to edit the associated item.
$canEdit = AssociationsHelper::allowEdit($extensionName, $typeName, $itemId);
// Check if item can be checked out
$canCheckout = AssociationsHelper::canCheckinItem($extensionName, $typeName, $itemId);
// Disable language if user is not allowed to edit the item associated to it.
$options[$langCode]->disable = !($canEdit && $canCheckout);
}
else
{
// New item, id = 0 and disabled if user is not allowed to create new items.
$options[$langCode]->value = $language->lang_code . ':0:add';
// Disable language if user is not allowed to create items.
$options[$langCode]->disable = !$canCreate;
}
}
return array_merge(parent::getOptions(), $options);
}
}
models/fields/itemtype.php 0000604 00000002771 15245557232 0011663 0 ustar 00 <?php
/**
* @package Joomla.Administrator
* @subpackage com_associations
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
JLoader::register('AssociationsHelper', JPATH_ADMINISTRATOR . '/components/com_associations/helpers/associations.php');
JFormHelper::loadFieldClass('groupedlist');
/**
* A drop down containing all component item types that implement associations.
*
* @since 3.7.0
*/
class JFormFieldItemType extends JFormFieldGroupedList
{
/**
* The form field type.
*
* @var string
*
* @since 3.7.0
*/
protected $type = 'ItemType';
/**
* Method to get the field input markup.
*
* @return array The field option objects as a nested array in groups.
*
* @since 3.7.0
*
* @throws UnexpectedValueException
*/
protected function getGroups()
{
$options = array();
$extensions = AssociationsHelper::getSupportedExtensions();
foreach ($extensions as $extension)
{
if ($extension->get('associationssupport') === true)
{
foreach ($extension->get('types') as $type)
{
$context = $extension->get('component') . '.' . $type->get('name');
$options[$extension->get('title')][] = JHtml::_('select.option', $context, $type->get('title'));
}
}
}
// Sort by alpha order.
uksort($options, 'strnatcmp');
// Add options to parent array.
return array_merge(parent::getGroups(), $options);
}
}
models/fields/modalassociation.php 0000604 00000006557 15245557232 0013362 0 ustar 00 <?php
/**
* @package Joomla.Administrator
* @subpackage com_associations
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Supports a modal item picker.
*
* @since 3.7.0
*/
class JFormFieldModalAssociation extends JFormField
{
/**
* The form field type.
*
* @var string
* @since 3.7.0
*/
protected $type = 'Modal_Association';
/**
* Method to get the field input markup.
*
* @return string The field input markup.
*
* @since 3.7.0
*/
protected function getInput()
{
// The active item id field.
$value = (int) $this->value > 0 ? (int) $this->value : '';
// Build the script.
$script = array();
// Select button script
$script[] = 'function jSelectAssociation_' . $this->id . '(id) {';
$script[] = ' target = document.getElementById("target-association");';
$script[] = ' document.getElementById("target-association").src = target.getAttribute("data-editurl") + '
. '"&task=" + target.getAttribute("data-item") + ".edit" + "&id=" + id';
$script[] = ' jQuery("#associationSelect' . $this->id . 'Modal").modal("hide");';
$script[] = '}';
// Add the script to the document head.
JFactory::getDocument()->addScriptDeclaration(implode("\n", $script));
// Setup variables for display.
$html = array();
$linkAssociations = 'index.php?option=com_associations&view=associations&layout=modal&tmpl=component'
. '&forcedItemType=' . JFactory::getApplication()->input->get('itemtype', '', 'string') . '&function=jSelectAssociation_' . $this->id;
$linkAssociations .= "&forcedLanguage=' + document.getElementById('target-association').getAttribute('data-language') + '";
$urlSelect = $linkAssociations . '&' . JSession::getFormToken() . '=1';
// Select custom association button
$html[] = '<button'
. ' type="button"'
. ' id="select-change"'
. ' class="btn' . ($value ? '' : ' hidden') . '"'
. ' data-toggle="modal"'
. ' data-select="' . JText::_('COM_ASSOCIATIONS_SELECT_TARGET') . '"'
. ' data-change="' . JText::_('COM_ASSOCIATIONS_CHANGE_TARGET') . '"'
. ' data-target="#associationSelect' . $this->id . 'Modal">'
. '<span class="icon-file" aria-hidden="true"></span>'
. '<span id="select-change-text"></span>'
. '</button>';
// Clear association button
$html[] = '<button'
. ' type="button"'
. ' class="btn' . ($value ? '' : ' hidden') . '"'
. ' onclick="return Joomla.submitbutton(\'undo-association\');"'
. ' id="remove-assoc">'
. '<span class="icon-remove" aria-hidden="true"></span>' . JText::_('JCLEAR')
. '</button>';
$html[] = '<input type="hidden" id="' . $this->id . '_id" name="' . $this->name . '" value="' . $value . '" />';
// Select custom association modal
$html[] = JHtml::_(
'bootstrap.renderModal',
'associationSelect' . $this->id . 'Modal',
array(
'title' => JText::_('COM_ASSOCIATIONS_SELECT_TARGET'),
'backdrop' => 'static',
'url' => $urlSelect,
'height' => '400px',
'width' => '800px',
'bodyHeight' => '70',
'modalWidth' => '80',
'footer' => '<button type="button" class="btn" data-dismiss="modal">'
. JText::_("JLIB_HTML_BEHAVIOR_CLOSE") . '</button>',
)
);
return implode("\n", $html);
}
}
models/associations.php 0000604 00000034156 15245557232 0011256 0 ustar 00 <?php
/**
* @package Joomla.Administrator
* @subpackage com_associations
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Methods supporting a list of article records.
*
* @since 3.7.0
*/
class AssociationsModelAssociations extends JModelList
{
/**
* Constructor.
*
* @param array $config An optional associative array of configuration settings.
*
* @since 3.7.0
*
* @see JController
*/
public function __construct($config = array())
{
if (empty($config['filter_fields']))
{
$config['filter_fields'] = array(
'id',
'title',
'ordering',
'itemtype',
'language',
'association',
'menutype',
'menutype_title',
'level',
'state',
'category_id',
'category_title',
'access',
'access_level',
);
}
parent::__construct($config);
}
/**
* Method to auto-populate the model state.
*
* Note. Calling getState in this method will result in recursion.
*
* @param string $ordering An optional ordering field.
* @param string $direction An optional direction (asc|desc).
*
* @return void
*
* @since 3.7.0
*/
protected function populateState($ordering = 'ordering', $direction = 'asc')
{
$app = JFactory::getApplication();
$forcedLanguage = $app->input->get('forcedLanguage', '', 'cmd');
$forcedItemType = $app->input->get('forcedItemType', '', 'string');
// Adjust the context to support modal layouts.
if ($layout = $app->input->get('layout'))
{
$this->context .= '.' . $layout;
}
// Adjust the context to support forced languages.
if ($forcedLanguage)
{
$this->context .= '.' . $forcedLanguage;
}
// Adjust the context to support forced component item types.
if ($forcedItemType)
{
$this->context .= '.' . $forcedItemType;
}
$this->setState('itemtype', $this->getUserStateFromRequest($this->context . '.itemtype', 'itemtype', '', 'string'));
$this->setState('language', $this->getUserStateFromRequest($this->context . '.language', 'language', '', 'string'));
$this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string'));
$this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd'));
$this->setState('filter.category_id', $this->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id', '', 'cmd'));
$this->setState('filter.menutype', $this->getUserStateFromRequest($this->context . '.filter.menutype', 'filter_menutype', '', 'string'));
$this->setState('filter.access', $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', '', 'string'));
$this->setState('filter.level', $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', '', 'cmd'));
// List state information.
parent::populateState($ordering, $direction);
// Force a language.
if (!empty($forcedLanguage))
{
$this->setState('language', $forcedLanguage);
}
// Force a component item type.
if (!empty($forcedItemType))
{
$this->setState('itemtype', $forcedItemType);
}
}
/**
* Method to get a store id based on model configuration state.
*
* This is necessary because the model is used by the component and
* different modules that might need different sets of data or different
* ordering requirements.
*
* @param string $id A prefix for the store id.
*
* @return string A store id.
*
* @since 3.7.0
*/
protected function getStoreId($id = '')
{
// Compile the store id.
$id .= ':' . $this->getState('itemtype');
$id .= ':' . $this->getState('language');
$id .= ':' . $this->getState('filter.search');
$id .= ':' . $this->getState('filter.state');
$id .= ':' . $this->getState('filter.category_id');
$id .= ':' . $this->getState('filter.menutype');
$id .= ':' . $this->getState('filter.access');
$id .= ':' . $this->getState('filter.level');
return parent::getStoreId($id);
}
/**
* Build an SQL query to load the list data.
*
* @return JDatabaseQuery|boolean
*
* @since 3.7.0
*/
protected function getListQuery()
{
$type = null;
list($extensionName, $typeName) = explode('.', $this->state->get('itemtype'));
$extension = AssociationsHelper::getSupportedExtension($extensionName);
$types = $extension->get('types');
if (array_key_exists($typeName, $types))
{
$type = $types[$typeName];
}
if (is_null($type))
{
return false;
}
// Create a new query object.
$user = JFactory::getUser();
$db = $this->getDbo();
$query = $db->getQuery(true);
$details = $type->get('details');
if (!array_key_exists('support', $details))
{
return false;
}
$support = $details['support'];
if (!array_key_exists('fields', $details))
{
return false;
}
$fields = $details['fields'];
// Main query.
$query->select($db->qn($fields['id'], 'id'))
->select($db->qn($fields['title'], 'title'))
->select($db->qn($fields['alias'], 'alias'));
if (!array_key_exists('tables', $details))
{
return false;
}
$tables = $details['tables'];
foreach ($tables as $key => $table)
{
$query->from($db->qn($table, $key));
}
if (!array_key_exists('joins', $details))
{
return false;
}
$joins = $details['joins'];
foreach ($joins as $join)
{
$query->join($join['type'], $db->qn($join['condition']));
}
// Join over the language.
$query->select($db->qn($fields['language'], 'language'))
->select($db->qn('l.title', 'language_title'))
->select($db->qn('l.image', 'language_image'))
->join('LEFT', $db->qn('#__languages', 'l') . ' ON ' . $db->qn('l.lang_code') . ' = ' . $db->qn($fields['language']));
// Join over the associations.
$query->select('COUNT(' . $db->qn('asso2.id') . ') > 1 AS ' . $db->qn('association'))
->join(
'LEFT',
$db->qn('#__associations', 'asso') . ' ON ' . $db->qn('asso.id') . ' = ' . $db->qn($fields['id'])
. ' AND ' . $db->qn('asso.context') . ' = ' . $db->quote($extensionName . '.' . 'item')
)
->join('LEFT', $db->qn('#__associations', 'asso2') . ' ON ' . $db->qn('asso2.key') . ' = ' . $db->qn('asso.key'));
// Prepare the group by clause.
$groupby = array(
$fields['id'],
$fields['title'],
$fields['language'],
'l.title',
'l.image',
);
// Select author for ACL checks.
if (!empty($fields['created_user_id']))
{
$query->select($db->qn($fields['created_user_id'], 'created_user_id'));
}
// Select checked out data for check in checkins.
if (!empty($fields['checked_out']) && !empty($fields['checked_out_time']))
{
$query->select($db->qn($fields['checked_out'], 'checked_out'))
->select($db->qn($fields['checked_out_time'], 'checked_out_time'));
// Join over the users.
$query->select($db->qn('u.name', 'editor'))
->join('LEFT', $db->qn('#__users', 'u') . ' ON ' . $db->qn('u.id') . ' = ' . $db->qn($fields['checked_out']));
$groupby[] = 'u.name';
}
// If component item type supports ordering, select the ordering also.
if (!empty($fields['ordering']))
{
$query->select($db->qn($fields['ordering'], 'ordering'));
}
// If component item type supports state, select the item state also.
if (!empty($fields['state']))
{
$query->select($db->qn($fields['state'], 'state'));
}
// If component item type supports level, select the level also.
if (!empty($fields['level']))
{
$query->select($db->qn($fields['level'], 'level'));
}
// If component item type supports categories, select the category also.
if (!empty($fields['catid']))
{
$query->select($db->qn($fields['catid'], 'catid'));
// Join over the categories.
$query->select($db->qn('c.title', 'category_title'))
->join('LEFT', $db->qn('#__categories', 'c') . ' ON ' . $db->qn('c.id') . ' = ' . $db->qn($fields['catid']));
$groupby[] = 'c.title';
}
// If component item type supports menu type, select the menu type also.
if (!empty($fields['menutype']))
{
$query->select($db->qn($fields['menutype'], 'menutype'));
// Join over the menu types.
$query->select($db->qn('mt.title', 'menutype_title'))
->select($db->qn('mt.id', 'menutypeid'))
->join('LEFT', $db->qn('#__menu_types', 'mt') . ' ON ' . $db->qn('mt.menutype') . ' = ' . $db->qn($fields['menutype']));
$groupby[] = 'mt.title';
$groupby[] = 'mt.id';
}
// If component item type supports access level, select the access level also.
if (array_key_exists('acl', $support) && $support['acl'] == true && !empty($fields['access']))
{
$query->select($db->qn($fields['access'], 'access'));
// Join over the access levels.
$query->select($db->qn('ag.title', 'access_level'))
->join('LEFT', $db->qn('#__viewlevels', 'ag') . ' ON ' . $db->qn('ag.id') . ' = ' . $db->qn($fields['access']));
$groupby[] = 'ag.title';
// Implement View Level Access.
if (!$user->authorise('core.admin', $extensionName))
{
$query->where($fields['access'] . ' IN (' . implode(',', $user->getAuthorisedViewLevels()) . ')');
}
}
// If component item type is menus we need to remove the root item and the administrator menu.
if ($extensionName === 'com_menus')
{
$query->where($db->qn($fields['id']) . ' > 1')
->where($db->qn('a.client_id') . ' = 0');
}
// If component item type is category we need to remove all other component categories.
if ($typeName === 'category')
{
$query->where($db->qn('a.extension') . ' = ' . $db->quote($extensionName));
}
// Filter on the language.
if ($language = $this->getState('language'))
{
$query->where($db->qn($fields['language']) . ' = ' . $db->quote($language));
}
// Filter by item state.
$state = $this->getState('filter.state');
if (is_numeric($state))
{
$query->where($db->qn($fields['state']) . ' = ' . (int) $state);
}
elseif ($state === '')
{
$query->where($db->qn($fields['state']) . ' IN (0, 1)');
}
// Filter on the category.
$baselevel = 1;
if ($categoryId = $this->getState('filter.category_id'))
{
$categoryTable = JTable::getInstance('Category', 'JTable');
$categoryTable->load($categoryId);
$baselevel = (int) $categoryTable->level;
$query->where($db->qn('c.lft') . ' >= ' . (int) $categoryTable->lft)
->where($db->qn('c.rgt') . ' <= ' . (int) $categoryTable->rgt);
}
// Filter on the level.
if ($level = $this->getState('filter.level'))
{
$query->where($db->qn('a.level') . ' <= ' . ((int) $level + (int) $baselevel - 1));
}
// Filter by menu type.
if ($menutype = $this->getState('filter.menutype'))
{
$query->where($fields['menutype'] . ' = ' . $db->quote($menutype));
}
// Filter by access level.
if ($access = $this->getState('filter.access'))
{
$query->where($fields['access'] . ' = ' . (int) $access);
}
// Filter by search in name.
if ($search = $this->getState('filter.search'))
{
if (stripos($search, 'id:') === 0)
{
$query->where($db->qn($fields['id']) . ' = ' . (int) substr($search, 3));
}
else
{
$search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%'));
$query->where('(' . $db->qn($fields['title']) . ' LIKE ' . $search
. ' OR ' . $db->qn($fields['alias']) . ' LIKE ' . $search . ')'
);
}
}
// Add the group by clause
$query->group($db->qn($groupby));
// Add the list ordering clause
$listOrdering = $this->state->get('list.ordering', 'id');
$orderDirn = $this->state->get('list.direction', 'ASC');
$query->order($db->escape($listOrdering) . ' ' . $db->escape($orderDirn));
return $query;
}
/**
* Delete associations from #__associations table.
*
* @param string $context The associations context. Empty for all.
* @param string $key The associations key. Empty for all.
*
* @return boolean True on success.
*
* @since 3.7.0
*/
public function purge($context = '', $key = '')
{
$app = JFactory::getApplication();
$db = $this->getDbo();
$query = $db->getQuery(true)->delete($db->qn('#__associations'));
// Filter by associations context.
if ($context)
{
$query->where($db->qn('context') . ' = ' . $db->quote($context));
}
// Filter by key.
if ($key)
{
$query->where($db->qn('key') . ' = ' . $db->quote($key));
}
$db->setQuery($query);
try
{
$db->execute();
}
catch (JDatabaseExceptionExecuting $e)
{
$app->enqueueMessage(JText::_('COM_ASSOCIATIONS_PURGE_FAILED'), 'error');
return false;
}
$app->enqueueMessage(
JText::_((int) $db->getAffectedRows() > 0 ? 'COM_ASSOCIATIONS_PURGE_SUCCESS' : 'COM_ASSOCIATIONS_PURGE_NONE'),
'message'
);
return true;
}
/**
* Delete orphans from the #__associations table.
*
* @param string $context The associations context. Empty for all.
* @param string $key The associations key. Empty for all.
*
* @return boolean True on success
*
* @since 3.7.0
*/
public function clean($context = '', $key = '')
{
$app = JFactory::getApplication();
$db = $this->getDbo();
$query = $db->getQuery(true)
->select($db->qn('key') . ', COUNT(*)')
->from($db->qn('#__associations'))
->group($db->qn('key'))
->having('COUNT(*) = 1');
// Filter by associations context.
if ($context)
{
$query->where($db->qn('context') . ' = ' . $db->quote($context));
}
// Filter by key.
if ($key)
{
$query->where($db->qn('key') . ' = ' . $db->quote($key));
}
$db->setQuery($query);
$assocKeys = $db->loadObjectList();
$count = 0;
// We have orphans. Let's delete them.
foreach ($assocKeys as $value)
{
$query->clear()
->delete($db->qn('#__associations'))
->where($db->qn('key') . ' = ' . $db->quote($value->key));
$db->setQuery($query);
try
{
$db->execute();
}
catch (JDatabaseExceptionExecuting $e)
{
$app->enqueueMessage(JText::_('COM_ASSOCIATIONS_DELETE_ORPHANS_FAILED'), 'error');
return false;
}
$count += (int) $db->getAffectedRows();
}
$app->enqueueMessage(
JText::_($count > 0 ? 'COM_ASSOCIATIONS_DELETE_ORPHANS_SUCCESS' : 'COM_ASSOCIATIONS_DELETE_ORPHANS_NONE'),
'message'
);
return true;
}
}
models/forms/association.xml 0000604 00000000665 15245557232 0012230 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<form>
<fieldset>
<field
name="itemlanguage"
type="itemlanguage"
label="COM_ASSOCIATIONS_ITEM_FIELD_LANGUAGE_LABEL"
description="COM_ASSOCIATIONS_ITEM_FIELD_LANGUAGE_DESC"
>
<option value="">COM_ASSOCIATIONS_SELECT_TARGET_LANGUAGE</option>
</field>
<field
name="modalassociation"
type="modalassociation"
/>
</fieldset>
<fields name="params">
</fields>
</form>
models/forms/filter_associations.xml 0000604 00000005664 15245557232 0013764 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<form>
<field
name="itemtype"
type="itemtype"
label="COM_ASSOCIATIONS_COMPONENT_SELECTOR_LABEL"
description="COM_ASSOCIATIONS_COMPONENT_SELECTOR_DESC"
filtermode="selector"
onchange="jQuery('select[id^=\'filter_\']').val('');jQuery('select[id^=\'list_\']').val('');this.form.submit();"
>
<option value="">COM_ASSOCIATIONS_FILTER_SELECT_ITEM_TYPE</option>
</field>
<field
name="language"
type="contentlanguage"
label="JOPTION_FILTER_LANGUAGE"
description="JOPTION_FILTER_LANGUAGE_DESC"
filtermode="selector"
onchange="this.form.submit();"
>
<option value="">JOPTION_SELECT_LANGUAGE</option>
</field>
<fields name="filter">
<field
name="search"
type="text"
inputmode="search"
label="COM_ASSOCIATIONS_FILTER_SEARCH_LABEL"
description="COM_ASSOCIATIONS_FILTER_SEARCH_DESC"
hint="JSEARCH_FILTER"
/>
<field
name="state"
type="status"
label="JOPTION_FILTER_PUBLISHED"
description="JOPTION_FILTER_PUBLISHED_DESC"
onchange="this.form.submit();"
>
<option value="">JOPTION_SELECT_PUBLISHED</option>
</field>
<field
name="category_id"
type="category"
label="JOPTION_FILTER_CATEGORY"
description="JOPTION_FILTER_CATEGORY_DESC"
published="0,1,2"
extension="dynamic"
onchange="this.form.submit();"
>
<option value="">JOPTION_SELECT_CATEGORY</option>
</field>
<field
name="menutype"
type="menu"
label="COM_ASSOCIATIONS_FILTER_MENUTYPE_LABEL"
description="COM_ASSOCIATIONS_FILTER_MENUTYPE_DESC"
clientid="0"
onchange="this.form.submit();"
>
<option value="">COM_ASSOCIATIONS_SELECT_MENU</option>
</field>
<field
name="access"
type="accesslevel"
label="JOPTION_FILTER_ACCESS"
description="JOPTION_FILTER_ACCESS_DESC"
onchange="this.form.submit();"
>
<option value="">JOPTION_SELECT_ACCESS</option>
</field>
<field
name="level"
type="integer"
label="JOPTION_FILTER_LEVEL"
description="JOPTION_FILTER_LEVEL_DESC"
first="1"
last="10"
step="1"
onchange="this.form.submit();"
>
<option value="">JOPTION_SELECT_MAX_LEVELS</option>
</field>
</fields>
<fields name="list">
<field
name="fullordering"
type="list"
default="id ASC"
onchange="this.form.submit();"
validate="options"
>
<option value="">JGLOBAL_SORT_BY</option>
<option value="state ASC">JSTATUS_ASC</option>
<option value="state DESC">JSTATUS_DESC</option>
<option value="title ASC">JGLOBAL_TITLE_ASC</option>
<option value="title DESC">JGLOBAL_TITLE_DESC</option>
<option value="access_level ASC">JGRID_HEADING_ACCESS_ASC</option>
<option value="access_level DESC">JGRID_HEADING_ACCESS_DESC</option>
<option value="id ASC">JGRID_HEADING_ID_ASC</option>
<option value="id DESC">JGRID_HEADING_ID_DESC</option>
</field>
<field
name="limit"
type="limitbox"
default="25"
class="input-mini"
onchange="this.form.submit();"
/>
</fields>
</form>
views/association/tmpl/edit.php 0000604 00000005763 15245557232 0012650 0 ustar 00 <?php
/**
* @package Joomla.Administrator
* @subpackage com_associations
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
JHtml::_('behavior.formvalidator');
JHtml::_('behavior.keepalive');
JHtml::_('formbehavior.chosen', 'select');
JHtml::_('script', 'com_associations/sidebyside.js', false, true);
JHtml::_('stylesheet', 'com_associations/sidebyside.css', array(), true);
$options = array(
'layout' => $this->app->input->get('layout', '', 'string'),
'itemtype' => $this->itemtype,
'id' => $this->referenceId,
);
?>
<button id="toogle-left-panel" class="btn btn-small"
data-show-reference="<?php echo JText::_('COM_ASSOCIATIONS_EDIT_SHOW_REFERENCE'); ?>"
data-hide-reference="<?php echo JText::_('COM_ASSOCIATIONS_EDIT_HIDE_REFERENCE'); ?>"><?php echo JText::_('COM_ASSOCIATIONS_EDIT_HIDE_REFERENCE'); ?>
</button>
<form action="<?php echo JRoute::_('index.php?option=com_associations&view=association&' . http_build_query($options)); ?>" method="post" name="adminForm" id="adminForm" data-associatedview="<?php echo $this->typeName; ?>">
<div class="sidebyside">
<div class="outer-panel" id="left-panel">
<div class="inner-panel">
<h3><?php echo JText::_('COM_ASSOCIATIONS_REFERENCE_ITEM'); ?></h3>
<iframe id="reference-association" name="reference-association" title="reference-association"
src="<?php echo JRoute::_($this->editUri . '&task=' . $this->typeName . '.edit&id=' . (int) $this->referenceId); ?>"
height="400" width="400"
data-action="edit"
data-item="<?php echo $this->typeName; ?>"
data-id="<?php echo $this->referenceId; ?>"
data-title="<?php echo $this->referenceTitle; ?>"
data-title-value="<?php echo $this->referenceTitleValue; ?>"
data-language="<?php echo $this->referenceLanguage; ?>"
data-editurl="<?php echo JRoute::_($this->editUri); ?>">
</iframe>
</div>
</div>
<div class="outer-panel" id="right-panel">
<div class="inner-panel">
<div class="language-selector">
<h3 class="target-text"><?php echo JText::_('COM_ASSOCIATIONS_ASSOCIATED_ITEM'); ?></h3>
<?php echo $this->form->getInput('modalassociation'); ?>
<?php echo $this->form->getInput('itemlanguage'); ?>
</div>
<iframe id="target-association" name="target-association" title="target-association"
src="<?php echo $this->defaultTargetSrc; ?>"
height="400" width="400"
data-action="<?php echo $this->targetAction; ?>"
data-item="<?php echo $this->typeName; ?>"
data-id="<?php echo $this->targetId; ?>"
data-title="<?php echo $this->targetTitle; ?>"
data-language="<?php echo $this->targetLanguage; ?>"
data-editurl="<?php echo JRoute::_($this->editUri); ?>">
</iframe>
</div>
</div>
</div>
<input type="hidden" name="task" value="" />
<input type="hidden" name="target-id" id="target-id" value="" />
<?php echo JHtml::_('form.token'); ?>
</form>
views/association/view.html.php 0000604 00000013137 15245557232 0012656 0 ustar 00 <?php
/**
* @package Joomla.Administrator
* @subpackage com_associations
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\Utilities\ArrayHelper;
/**
* View class for a list of articles.
*
* @since 3.7.0
*/
class AssociationsViewAssociation extends JViewLegacy
{
/**
* An array of items
*
* @var array
*
* @since 3.7.0
*/
protected $items;
/**
* The pagination object
*
* @var JPagination
*
* @since 3.7.0
*/
protected $pagination;
/**
* The model state
*
* @var object
*
* @since 3.7.0
*/
protected $state;
/**
* Selected item type properties.
*
* @var Registry
*
* @since 3.7.0
*/
public $itemType = null;
/**
* Display the view
*
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
*
* @return void
*
* @since 3.7.0
* @throws Exception
*/
public function display($tpl = null)
{
// Check for errors.
if (count($errors = $this->get('Errors')))
{
throw new Exception(implode("\n", $errors), 500);
}
$this->app = JFactory::getApplication();
$this->form = $this->get('Form');
$input = $this->app->input;
$this->referenceId = $input->get('id', 0, 'int');
list($extensionName, $typeName) = explode('.', $input->get('itemtype', '', 'string'));
$extension = AssociationsHelper::getSupportedExtension($extensionName);
$types = $extension->get('types');
if (array_key_exists($typeName, $types))
{
$this->type = $types[$typeName];
$this->typeSupports = array();
$details = $this->type->get('details');
$this->save2copy = false;
if (array_key_exists('support', $details))
{
$support = $details['support'];
$this->typeSupports = $support;
}
if (!empty($this->typeSupports['save2copy']))
{
$this->save2copy = true;
}
}
$this->extensionName = $extensionName;
$this->typeName = $typeName;
$this->itemtype = $extensionName . '.' . $typeName;
$languageField = AssociationsHelper::getTypeFieldName($extensionName, $typeName, 'language');
$referenceId = $input->get('id', 0, 'int');
$reference = ArrayHelper::fromObject(AssociationsHelper::getItem($extensionName, $typeName, $referenceId));
$this->referenceLanguage = $reference[$languageField];
$this->referenceTitle = AssociationsHelper::getTypeFieldName($extensionName, $typeName, 'title');
$this->referenceTitleValue = $reference[$this->referenceTitle];
$options = array(
'option' => $typeName === 'category' ? 'com_categories' : $extensionName,
'view' => $typeName,
'extension' => $extensionName,
'tmpl' => 'component',
);
// Reference and target edit links.
$this->editUri = 'index.php?' . http_build_query($options);
// Get target language.
$this->targetId = '0';
$this->targetLanguage = '';
$this->defaultTargetSrc = '';
$this->targetAction = '';
$this->targetTitle = '';
if ($target = $input->get('target', '', 'string'))
{
$matches = preg_split("#[\:]+#", $target);
$this->targetAction = $matches[2];
$this->targetId = $matches[1];
$this->targetLanguage = $matches[0];
$this->targetTitle = AssociationsHelper::getTypeFieldName($extensionName, $typeName, 'title');
$task = $typeName . '.' . $this->targetAction;
/* Let's put the target src into a variable to use in the javascript code
* to avoid race conditions when the reference iframe loads.
*/
$document = JFactory::getDocument();
$document->addScriptOptions('targetSrc', JRoute::_($this->editUri . '&task=' . $task . '&id=' . (int) $this->targetId));
$this->form->setValue('itemlanguage', '', $this->targetLanguage . ':' . $this->targetId . ':' . $this->targetAction);
}
$this->addToolbar();
parent::display($tpl);
}
/**
* Add the page title and toolbar.
*
* @return void
*
* @since 3.7.0
*/
protected function addToolbar()
{
// Hide main menu.
JFactory::getApplication()->input->set('hidemainmenu', 1);
$helper = AssociationsHelper::getExtensionHelper($this->extensionName);
$title = $helper->getTypeTitle($this->typeName);
$languageKey = strtoupper($this->extensionName . '_' . $title . 'S');
if ($this->typeName === 'category')
{
$languageKey = strtoupper($this->extensionName) . '_CATEGORIES';
}
JToolbarHelper::title(JText::sprintf('COM_ASSOCIATIONS_TITLE_EDIT', JText::_($this->extensionName), JText::_($languageKey)), 'contract assoc');
$bar = JToolbar::getInstance('toolbar');
$bar->appendButton(
'Custom', '<button onclick="Joomla.submitbutton(\'reference\')" '
. 'class="btn btn-small btn-success"><span class="icon-apply icon-white" aria-hidden="true"></span>'
. JText::_('COM_ASSOCIATIONS_SAVE_REFERENCE') . '</button>', 'reference'
);
$bar->appendButton(
'Custom', '<button onclick="Joomla.submitbutton(\'target\')" '
. 'class="btn btn-small btn-success"><span class="icon-apply icon-white" aria-hidden="true"></span>'
. JText::_('COM_ASSOCIATIONS_SAVE_TARGET') . '</button>', 'target'
);
if ($this->typeName === 'category' || $this->extensionName === 'com_menus' || $this->save2copy === true)
{
JToolBarHelper::custom('copy', 'copy.png', '', 'COM_ASSOCIATIONS_COPY_REFERENCE', false);
}
JToolbarHelper::cancel('association.cancel', 'JTOOLBAR_CLOSE');
JToolbarHelper::help('JHELP_COMPONENTS_ASSOCIATIONS_EDIT');
JHtmlSidebar::setAction('index.php?option=com_associations');
}
}
views/associations/view.html.php 0000604 00000014071 15245557232 0013037 0 ustar 00 <?php
/**
* @package Joomla.Administrator
* @subpackage com_associations
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* View class for a list of articles.
*
* @since 3.7.0
*/
class AssociationsViewAssociations extends JViewLegacy
{
/**
* An array of items
*
* @var array
*
* @since 3.7.0
*/
protected $items;
/**
* The pagination object
*
* @var JPagination
*
* @since 3.7.0
*/
protected $pagination;
/**
* The model state
*
* @var object
*
* @since 3.7.0
*/
protected $state;
/**
* Selected item type properties.
*
* @var Registry
*
* @since 3.7.0
*/
public $itemType = null;
/**
* Display the view
*
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
*
* @return void
*
* @since 3.7.0
*/
public function display($tpl = null)
{
$this->state = $this->get('State');
$this->filterForm = $this->get('FilterForm');
$this->activeFilters = $this->get('ActiveFilters');
if (!JLanguageAssociations::isEnabled())
{
$link = JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . AssociationsHelper::getLanguagefilterPluginId());
JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_ASSOCIATIONS_ERROR_NO_ASSOC', $link), 'warning');
}
elseif ($this->state->get('itemtype') == '' || $this->state->get('language') == '')
{
JFactory::getApplication()->enqueueMessage(JText::_('COM_ASSOCIATIONS_NOTICE_NO_SELECTORS'), 'notice');
}
else
{
$type = null;
list($extensionName, $typeName) = explode('.', $this->state->get('itemtype'));
$extension = AssociationsHelper::getSupportedExtension($extensionName);
$types = $extension->get('types');
if (array_key_exists($typeName, $types))
{
$type = $types[$typeName];
}
$this->itemType = $type;
if (is_null($type))
{
JFactory::getApplication()->enqueueMessage(JText::_('COM_ASSOCIATIONS_ERROR_NO_TYPE'), 'warning');
}
else
{
$this->extensionName = $extensionName;
$this->typeName = $typeName;
$this->typeSupports = array();
$this->typeFields = array();
$details = $type->get('details');
if (array_key_exists('support', $details))
{
$support = $details['support'];
$this->typeSupports = $support;
}
if (array_key_exists('fields', $details))
{
$fields = $details['fields'];
$this->typeFields = $fields;
}
// Dynamic filter form.
// This selectors doesn't have to activate the filter bar.
unset($this->activeFilters['itemtype']);
unset($this->activeFilters['language']);
// Remove filters options depending on selected type.
if (empty($support['state']))
{
unset($this->activeFilters['state']);
$this->filterForm->removeField('state', 'filter');
}
if (empty($support['category']))
{
unset($this->activeFilters['category_id']);
$this->filterForm->removeField('category_id', 'filter');
}
if ($extensionName !== 'com_menus')
{
unset($this->activeFilters['menutype']);
$this->filterForm->removeField('menutype', 'filter');
}
if (empty($support['level']))
{
unset($this->activeFilters['level']);
$this->filterForm->removeField('level', 'filter');
}
if (empty($support['acl']))
{
unset($this->activeFilters['access']);
$this->filterForm->removeField('access', 'filter');
}
// Add extension attribute to category filter.
if (empty($support['catid']))
{
$this->filterForm->setFieldAttribute('category_id', 'extension', $extensionName, 'filter');
if ($this->getLayout() == 'modal')
{
// We need to change the category filter to only show categories tagged to All or to the forced language.
if ($forcedLanguage = JFactory::getApplication()->input->get('forcedLanguage', '', 'CMD'))
{
$this->filterForm->setFieldAttribute('category_id', 'language', '*,' . $forcedLanguage, 'filter');
}
}
}
$this->items = $this->get('Items');
$this->pagination = $this->get('Pagination');
$linkParameters = array(
'layout' => 'edit',
'itemtype' => $extensionName . '.' . $typeName,
'task' => 'association.edit',
);
$this->editUri = 'index.php?option=com_associations&view=association&' . http_build_query($linkParameters);
}
}
// Check for errors.
if (count($errors = $this->get('Errors')))
{
throw new Exception(implode("\n", $errors), 500);
}
$this->addToolbar();
// Will add sidebar if needed $this->sidebar = JHtmlSidebar::render();
parent::display($tpl);
}
/**
* Add the page title and toolbar.
*
* @return void
*
* @since 3.7.0
*/
protected function addToolbar()
{
$user = JFactory::getUser();
if (isset($this->typeName) && isset($this->extensionName))
{
$helper = AssociationsHelper::getExtensionHelper($this->extensionName);
$title = $helper->getTypeTitle($this->typeName);
$languageKey = strtoupper($this->extensionName . '_' . $title . 'S');
if ($this->typeName === 'category')
{
$languageKey = strtoupper($this->extensionName) . '_CATEGORIES';
}
JToolbarHelper::title(
JText::sprintf(
'COM_ASSOCIATIONS_TITLE_LIST', JText::_($this->extensionName), JText::_($languageKey)
), 'contract assoc'
);
}
else
{
JToolbarHelper::title(JText::_('COM_ASSOCIATIONS_TITLE_LIST_SELECT'), 'contract assoc');
}
if ($user->authorise('core.admin', 'com_associations') || $user->authorise('core.options', 'com_associations'))
{
if (!isset($this->typeName))
{
JToolbarHelper::custom('associations.purge', 'purge', 'purge', 'COM_ASSOCIATIONS_PURGE', false, false);
JToolbarHelper::custom('associations.clean', 'refresh', 'refresh', 'COM_ASSOCIATIONS_DELETE_ORPHANS', false, false);
}
JToolbarHelper::preferences('com_associations');
}
JToolbarHelper::help('JHELP_COMPONENTS_ASSOCIATIONS');
}
}
views/associations/tmpl/modal.php 0000604 00000015353 15245557232 0013176 0 ustar 00 <?php
/**
* @package Joomla.Administrator
* @subpackage com_associations
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
$app = JFactory::getApplication();
if ($app->isClient('site'))
{
JSession::checkToken('get') or die(JText::_('JINVALID_TOKEN'));
}
JHtml::_('jquery.framework');
JHtml::_('bootstrap.tooltip', '.hasTooltip', array('placement' => 'bottom'));
JHtml::_('behavior.multiselect');
JHtml::_('formbehavior.chosen', 'select');
$function = $app->input->getCmd('function', 'jSelectAssociation');
$listOrder = $this->escape($this->state->get('list.ordering'));
$listDirn = $this->escape($this->state->get('list.direction'));
$canManageCheckin = JFactory::getUser()->authorise('core.manage', 'com_checkin');
$colSpan = 4;
$iconStates = array(
-2 => 'icon-trash',
0 => 'icon-unpublish',
1 => 'icon-publish',
2 => 'icon-archive',
);
$app->getDocument()->addScriptDeclaration(
"jQuery(document).ready(function($) {
// Run function on parent window.
$('.select-link').on('click', function() {
if (self != top)
{
window.parent." . $function . "(this.getAttribute('data-id'));
}
});
});"
);
?>
<form action="<?php echo JRoute::_('index.php?option=com_associations&view=associations&layout=modal&tmpl=component&function='
. $function . '&' . JSession::getFormToken() . '=1'); ?>" method="post" name="adminForm" id="adminForm">
<?php if (!empty( $this->sidebar)) : ?>
<div id="j-sidebar-container" class="span2">
<?php echo $this->sidebar; ?>
</div>
<div id="j-main-container" class="span10">
<?php else : ?>
<div id="j-main-container">
<?php endif;?>
<?php echo JLayoutHelper::render('joomla.searchtools.default', array('view' => $this)); ?>
<?php if (empty($this->items)) : ?>
<div class="alert alert-no-items">
<?php echo JText::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
</div>
<?php else : ?>
<table class="table table-striped" id="associationsList">
<thead>
<tr>
<?php if (!empty($this->typeSupports['state'])) : ?>
<th width="1%" class="center nowrap">
<?php echo JHtml::_('searchtools.sort', 'JSTATUS', 'state', $listDirn, $listOrder); $colSpan++; ?>
</th>
<?php endif; ?>
<th class="nowrap">
<?php echo JHtml::_('searchtools.sort', 'JGLOBAL_TITLE', 'title', $listDirn, $listOrder); ?>
</th>
<th width="15%" class="nowrap">
<?php echo JText::_('JGRID_HEADING_LANGUAGE'); ?>
</th>
<th width="5%" class="nowrap">
<?php echo JHtml::_('searchtools.sort', 'COM_ASSOCIATIONS_HEADING_ASSOCIATION', 'association', $listDirn, $listOrder); ?>
</th>
<?php if (!empty($this->typeFields['menutype'])) : ?>
<th width="10%" class="nowrap">
<?php echo JHtml::_('searchtools.sort', 'COM_ASSOCIATIONS_HEADING_MENUTYPE', 'menutype_title', $listDirn, $listOrder); $colSpan++; ?>
</th>
<?php endif; ?>
<?php if (!empty($this->typeSupports['acl'])) : ?>
<th width="5%" class="nowrap hidden-phone">
<?php echo JHtml::_('searchtools.sort', 'JGRID_HEADING_ACCESS', 'access_level', $listDirn, $listOrder); $colSpan++; ?>
</th>
<?php endif; ?>
<th width="1%" class="nowrap hidden-phone">
<?php echo JHtml::_('searchtools.sort', 'JGRID_HEADING_ID', 'id', $listDirn, $listOrder); ?>
</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="<?php echo $colSpan; ?>">
<?php echo $this->pagination->getListFooter(); ?>
</td>
</tr>
</tfoot>
<tbody>
<?php foreach ($this->items as $i => $item) :
$canEdit = AssociationsHelper::allowEdit($this->extensionName, $this->typeName, $item->id);
$canCheckin = $canManageCheckin || AssociationsHelper::canCheckinItem($this->extensionName, $this->typeName, $item->id);
$isCheckout = AssociationsHelper::isCheckoutItem($this->extensionName, $this->typeName, $item->id);
?>
<tr class="row<?php echo $i % 2; ?>">
<?php if (!empty($this->typeSupports['state'])) : ?>
<td class="center">
<span class="<?php echo $iconStates[$this->escape($item->state)]; ?>" aria-hidden="true"></span>
</td>
<?php endif; ?>
<td class="nowrap has-context">
<?php if (isset($item->level)) : ?>
<?php echo JLayoutHelper::render('joomla.html.treeprefix', array('level' => $item->level)); ?>
<?php endif; ?>
<?php if (($canEdit && !$isCheckout) || ($canEdit && $canCheckin && $isCheckout)) : ?>
<a class="select-link" href="javascript:void(0);" data-id="<?php echo $item->id; ?>">
<?php echo $this->escape($item->title); ?></a>
<?php elseif ($canEdit && $isCheckout) : ?>
<?php echo JHtml::_('jgrid.checkedout', $i, $item->editor, $item->checked_out_time, 'associations.'); ?>
<span title="<?php echo JText::sprintf('JFIELD_ALIAS_LABEL', $this->escape($item->alias)); ?>">
<?php echo $this->escape($item->title); ?></span>
<?php else : ?>
<span title="<?php echo JText::sprintf('JFIELD_ALIAS_LABEL', $this->escape($item->alias)); ?>">
<?php echo $this->escape($item->title); ?></span>
<?php endif; ?>
<?php if (!empty($this->typeFields['alias'])) : ?>
<span class="small">
<?php echo JText::sprintf('JGLOBAL_LIST_ALIAS', $this->escape($item->alias)); ?>
</span>
<?php endif; ?>
<?php if (!empty($this->typeFields['catid'])) : ?>
<div class="small">
<?php echo JText::_('JCATEGORY') . ": " . $this->escape($item->category_title); ?>
</div>
<?php endif; ?>
</td>
<td class="small">
<?php echo JLayoutHelper::render('joomla.content.language', $item); ?>
</td>
<td>
<?php if (true || $item->association) : ?>
<?php echo AssociationsHelper::getAssociationHtmlList($this->extensionName, $this->typeName, (int) $item->id, $item->language, false, false); ?>
<?php endif; ?>
</td>
<?php if (!empty($this->typeFields['menutype'])) : ?>
<td class="small">
<?php echo $this->escape($item->menutype_title); ?>
</td>
<?php endif; ?>
<?php if (!empty($this->typeSupports['acl'])) : ?>
<td class="small hidden-phone">
<?php echo $this->escape($item->access_level); ?>
</td>
<?php endif; ?>
<td class="hidden-phone">
<?php echo $item->id; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<input type="hidden" name="task" value=""/>
<input type="hidden" name="forcedItemType" value="<?php echo $app->input->get('forcedItemType', '', 'string'); ?>" />
<input type="hidden" name="forcedLanguage" value="<?php echo $app->input->get('forcedLanguage', '', 'cmd'); ?>" />
<?php echo JHtml::_('form.token'); ?>
</div>
</form>
views/associations/tmpl/default.xml 0000604 00000000264 15245557232 0013532 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<metadata>
<layout title="COM_ASSOCIATIONS">
<message>
<![CDATA[COM_ASSOCIATIONS_XML_DESCRIPTION]]>
</message>
</layout>
</metadata>