Your IP : 216.73.216.190


Current Path : /proc/1908984/root/proc/2603263/cwd/
Upload File :
Current File : //proc/1908984/root/proc/2603263/cwd/aimycanonical.tar

fields/aimydownloadkey.php000064400000002373152344413770011742 0ustar00<?php
/*
 * Copyright (c) 2024 Aimy Extensions, Netzum Sorglos Software GmbH
 *
 * https://www.aimy-extensions.com/
 *
 * License: GNU GPLv2, see LICENSE.txt within distribution and/or
 *          https://www.aimy-extensions.com/software-license.html
 */
 defined( '_JEXEC' ) or die(); require_once( __DIR__ . '/../helpers/DownloadKeyHelper.php' ); use Joomla\CMS\Form\FormField; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use AimyCanonical\Helpers\DownloadKeyHelper; class JFormFieldAimyDownloadKey extends FormField { protected $type = 'aimydownloadkey'; protected $layout = 'joomla.form.field.text'; public function getInput() { if ( strpos( JVERSION, '3.' ) !== 0 ) { Factory::getDocument() ->addStyleDeclaration( '#fieldset-key .control-group { align-items: center; }' ); return '<div>' . Text::sprintf( 'AIMY_CNCL_DL_KEY_USE_DL_KEY_MANAGER', DownloadKeyHelper::getEditLink() ) . '</div>'; } Factory::getDocument() ->addStyleDeclaration( '#jform_params_dl_key,#jform_dl_key { min-width: 250px; }' ); return $this->getRenderer( $this->layout ) ->render( $this->getLayoutData() ); } protected function getLayoutData() { return array_merge( array( 'options' => array(), 'addonBefore' => '', 'addonAfter' => '', 'dirname' => '' ), parent::getLayoutData() ); } } 
fields/index.html000064400000000016152344413770010016 0ustar00<html></html>
forms/generic-attribs.xml000064400000003301152344413770011505 0ustar00<?xml version="1.0" encoding="UTF-8"?>
<form>
    <fields name="attribs">
        <fieldset name="aimy_cncl" label="Aimy Canonical">
            <field type="spacer" class="aimycanonical-intro"
                label="AIMY_CNCL_CANONICAL_PATH_INTRO" />
            <field name="aimy_cncl_cpath"
                type="text"
                default=""
                class="inputbox"
                label="AIMY_CNCL_CANONICAL_PATH_LBL"
                description="AIMY_CNCL_CANONICAL_PATH_DSC" />
            <field name="aimy_cncl_override"
                type="radio" default="0"
                class="btn-group btn-group-yesno"
                labelclass="control-group"
                label="AIMY_CNCL_CANONICAL_OVERRIDE_LBL"
                description="AIMY_CNCL_CANONICAL_OVERRIDE_DSC">
                  <option value="0">JNO</option>
                  <option value="1">JYES</option>
            </field>
            <field name="aimy_cncl_cdomain" type="text" default=""
                showon="aimy_cncl_override:1"
                class="inputbox"
                label="AIMY_CNCL_DOMAIN_LBL"
                description="AIMY_CNCL_OVERRIDE_DOMAIN_DSC" />
            <field name="aimy_cncl_cprotocol"
                showon="aimy_cncl_override:1"
                type="radio" default="http"
                class="btn-group btn-group-yesno"
                labelclass="control-group"
                label="AIMY_CNCL_PROTOCOL_LBL"
                description="AIMY_CNCL_OVERRIDE_PROTOCOL_DSC">
                  <option value="http">http</option>
                  <option value="https">https</option>
            </field>
        </fieldset>
    </fields>
</form>
<!-- vim: set ft=xml sts=4 sw=4 ts=4 ai et: -->
forms/generic-params.xml000064400000003300152344413770011317 0ustar00<?xml version="1.0" encoding="UTF-8"?>
<form>
    <fields name="params">
        <fieldset name="aimy_cncl" label="Aimy Canonical">
            <field type="spacer" class="aimycanonical-intro"
                label="AIMY_CNCL_CANONICAL_PATH_INTRO" />
            <field name="aimy_cncl_cpath"
                type="text"
                default=""
                class="inputbox"
                label="AIMY_CNCL_CANONICAL_PATH_LBL"
                description="AIMY_CNCL_CANONICAL_PATH_DSC" />
            <field name="aimy_cncl_override"
                type="radio" default="0"
                class="btn-group btn-group-yesno"
                labelclass="control-group"
                label="AIMY_CNCL_CANONICAL_OVERRIDE_LBL"
                description="AIMY_CNCL_CANONICAL_OVERRIDE_DSC">
                  <option value="0">JNO</option>
                  <option value="1">JYES</option>
            </field>
            <field name="aimy_cncl_cdomain" type="text" default=""
                showon="aimy_cncl_override:1"
                class="inputbox"
                label="AIMY_CNCL_DOMAIN_LBL"
                description="AIMY_CNCL_OVERRIDE_DOMAIN_DSC" />
            <field name="aimy_cncl_cprotocol"
                showon="aimy_cncl_override:1"
                type="radio" default="http"
                class="btn-group btn-group-yesno"
                labelclass="control-group"
                label="AIMY_CNCL_PROTOCOL_LBL"
                description="AIMY_CNCL_OVERRIDE_PROTOCOL_DSC">
                  <option value="http">http</option>
                  <option value="https">https</option>
            </field>
        </fieldset>
    </fields>
</form>
<!-- vim: set ft=xml sts=4 sw=4 ts=4 ai et: -->
forms/index.html000064400000000016152344413770007676 0ustar00<html></html>
helpers/DownloadKeyHelper.php000064400000014551152344413770012317 0ustar00<?php
/*
 * Copyright (c) 2024 Aimy Extensions, Netzum Sorglos Software GmbH
 *
 * https://www.aimy-extensions.com/
 *
 * License: GNU GPLv2, see LICENSE.txt within distribution and/or
 *          http://www.aimy-extensions.com/software-license.html
 */
 namespace AimyCanonical\Helpers; defined( '_JEXEC' ) or die(); use Joomla\CMS\Factory; use Joomla\CMS\Http\HttpFactory; use Joomla\CMS\Language\Text; use Joomla\CMS\HTML\HTMLHelper; use Joomla\Registry\Registry; abstract class DownloadKeyHelper { const V_KEY_MISSING = 0; const V_KEY_INVALID = 1; const V_KEY_DENIED = 2; const V_KEY_EXPIRED = 3; const V_KEY_GRANTED = 4; const V_KEY_FAILED = 5; static private $lastError = ''; static private $lastResponseData = array(); static private $serverBaseUrl = 'http://dl.aimy-extensions.com'; static public function getUpdatesiteId() { $db = Factory::getDbo(); $q = $db->getQuery( true ); $q->select( $db->quoteName( 'update_site_id' ) ) ->from( $db->quoteName( '#__update_sites' ) ) ->where( $db->quoteName( 'name' ) . ' = ' . $db->quote( self::getUpdateServerName() ) ); $db->setQuery( $q ); return $db->loadResult(); } static public function getExtensionId() { $db = Factory::getDbo(); $q = $db->getQuery( true ); $q->select( $db->quoteName( 'extension_id' ) ) ->from( $db->quoteName( '#__extensions' ) ) ->where( $db->quoteName( 'element' ) . ' = ' . $db->quote( self::getElementName() ) ); $db->setQuery( $q ); return $db->loadResult(); } static public function getEditLink() { if ( self::isJoomla3() ) { if ( 'plg' == 'com' ) { return 'index.php?option=com_config&view=component&' . 'component=com_aimycanonical'; } $link = 'index.php?option=com_plugins'; if ( ! empty( $id = self::getExtensionId() ) ) { return $link . '&task=plugin.edit&extension_id=' . $id; } return $link . '&view=plugins'; } if ( $id = self::getUpdatesiteId() ) { return 'index.php?option=com_installer&' . 'task=updatesite.edit&update_site_id=' . $id; } return 'index.php?option=com_installer&view=updatesite'; } static public function passKeyToUpdatesites( $key ) { $id = self::getUpdateSiteId(); if ( ! $id ) { throw new \RuntimeException( 'Failed to determine update site id of AimyCanonical' ); } $eqVal = ''; if ( ! empty( $key ) ) { $key = trim( $key ); if ( ! empty( $key ) ) { $eqVal = 'dl_key=' . $key; } } $db = Factory::getDbo(); $q = $db->getQuery( true ); $q->update( $db->quoteName( '#__update_sites' ) ) ->set( $db->quoteName( 'extra_query' ) . ' = ' . $db->quote( $eqVal ) ) ->where( $db->quoteName( 'update_site_id' ) . ' = ' . $db->quote( $id ) ); $db->setQuery( $q ); return $db->execute(); } static public function getKey() { $key = self::getKeyFromUpdatesites(); if ( self::isJoomla3() && empty( $key ) ) { $key = self::getKeyFromParams(); } return $key; } static public function getKeyFromUpdatesites() { $db = Factory::getDbo(); $q = $db->getQuery( true ); $q->select( $db->quoteName( 'extra_query' ) ) ->from( $db->quoteName( '#__update_sites' ) ) ->where( $db->quoteName( 'name' ) . ' = ' . $db->quote( self::getUpdateServerName() ) ); $db->setQuery( $q ); $rv = $db->loadResult(); if ( ! empty( $rv ) && preg_match( '#dl_key=(\S+)#', $rv, $m ) ) { return $m[ 1 ]; } return false; } static public function getKeyFromParams() { $params = self::getParams(); if ( $params->exists( 'dl_key' ) ) { return trim( $params->get( 'dl_key' ) ); } return false; } static public function validateKey( $key = false ) { if ( empty( $key ) ) { $key = self::getKey(); } $rv = new \StdClass(); $rv->state = self::sendValidationRequest( $key ); $rv->msg = false; $rv->data = self::$lastResponseData; $rv->valid = false; self::loadLanguageStrings(); switch ( $rv->state ) { case self::V_KEY_GRANTED: $rv->valid = true; break; case self::V_KEY_MISSING: $rv->msg = Text::sprintf( 'AIMY_CNCL_DL_KEY_MISSING', htmlspecialchars( self::getEditLink() ) ); break; case self::V_KEY_INVALID: $rv->msg = Text::sprintf( 'AIMY_CNCL_DL_KEY_INVALID', htmlspecialchars( self::getEditLink() ) ); break; case self::V_KEY_EXPIRED: $rv->msg = Text::sprintf( 'AIMY_CNCL_DL_KEY_EXPIRED', HtmlHelper::date( isset( $rv->data[ 'since' ] ) ? $rv->data[ 'since' ] : 'now', Text::_( 'DATE_FORMAT_FILTER_DATE' ) ), htmlspecialchars( 'https://www.aimy-extensions.com/joomla/canonical.html' ) ); if ( isset( $rv->data[ 'code' ] ) ) { $rv->msg .= ' ' . Text::sprintf( 'AIMY_CNCL_DL_KEY_CODE', $rv->data[ 'code'] ); } break; case self::V_KEY_DENIED: $rv->msg = Text::sprintf( 'AIMY_CNCL_DL_KEY_DENIED', htmlspecialchars( 'https://www.aimy-extensions.com/joomla/canonical.html' ) ); break; case self::V_KEY_FAILED: $rv->msg = Text::sprintf( 'AIMY_CNCL_DL_KEY_VALIDATION_FAILED', self::$lastError ); break; } return $rv; } static private function sendValidationRequest( $key ) { if ( empty( $key ) ) { return self::V_KEY_MISSING; } try { self::$lastError = self::$lastResponseData = ''; $resp = HttpFactory::getHttp()->get( self::$serverBaseUrl . '/check/key/plg_AimyCanonical/' . $key ); if ( is_object( $resp ) ) { if ( $resp->code != 200 ) { self::$lastError = 'HTTP ' . $resp->code; return self::V_KEY_FAILED; } $json = json_decode( $resp->body, true ); if ( ! is_array( $json ) or ! isset( $json[ 'rv' ] ) ) { throw new \RuntimeException( 'Failed to parse JSON data' ); } self::$lastResponseData = $json; switch( $json[ 'rv' ] ) { case 'invalid key': return self::V_KEY_INVALID; case 'expired': return self::V_KEY_EXPIRED; case 'denied': return self::V_KEY_DENIED; case 'granted': return self::V_KEY_GRANTED; } } } catch ( \Exception $e ) { self::$lastError = $e->getMessage(); return self::V_KEY_FAILED; } return self::V_KEY_FAILED; } static private function getUpdateServerName() { return 'Aimy Canonical PRO Update Server'; } static private function getElementName() { if ( 'plg' == 'com' ) { return 'com_aimycanonical'; } return 'aimycanonical'; } static private function loadLanguageStrings() { $n = 'plg_'; if ( ! empty( $jp = 'system' ) ) { $n .= $jp . '_'; } $n .= 'aimycanonical'; Factory::getLanguage()->load( $n, JPATH_ADMINISTRATOR ); } static private function isJoomla3() { return ( strpos( JVERSION, '3.' ) === 0 ); } static public function getParams() { $db = Factory::getDbo(); $q = $db->getQuery( true ); $q->select( $db->quoteName( 'params' ) ) ->from( $db->quoteName( '#__extensions' ) ) ->where( $db->quoteName( 'element' ) . ' = ' . $db->quote( self::getElementName() ) ); $db->setQuery( $q ); $rv = $db->loadResult(); if ( empty( $rv ) ) { return false; } $params = new Registry(); $params->loadString( $rv ); return $params; } } 
aimycanonical.php000064400000050220152344413770010075 0ustar00<?php
/*
 * Copyright (c) 2017-2024 Aimy Extensions, Netzum Sorglos Software GmbH
 * Copyright (c) 2013-2017 Aimy Extensions, Lingua-Systems Software GmbH
 *
 * https://www.aimy-extensions.com/
 *
 * License: GNU GPLv2, see LICENSE.txt within distribution and/or
 *          http://www.aimy-extensions.com/software-license.html
 */
 defined( '_JEXEC' ) or die(); use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Factory; use Joomla\CMS\Uri\Uri; use Joomla\CMS\Router\Router; use Joomla\CMS\Router\Route; use Joomla\CMS\HTML\HTMLHelper; class plgSystemAimyCanonical extends CMSPlugin { private $noindex = false; private $href = null; const TRAILING_SLASHES_AS_IS = 0; const TRAILING_SLASHES_REMOVE = 1; const TRAILING_SLASHES_ADD = 2; function onBeforeCompileHead() { $sef_on = self::get_joomla_config( 'sef', false ); $domain = $this->params->get( 'domain', isset( $_SERVER[ 'HTTP_HOST' ] ) ? $_SERVER[ 'HTTP_HOST' ] : '' ); $proto = $this->params->get( 'protocol', null ); $app = Factory::getApplication(); $doc = Factory::getDocument(); if ( $app->getName() != 'site' or $doc->getType() != 'html' ) { return; } if ( empty( $domain ) ) { return; } if ( intVal( Factory::getUser()->id ) > 0 ) { $doc->addCustomTag( '<!-- Aimy Canonical: canonical link tag omitted ' . 'as you are logged in -->' ); return; } if ( $robots = $doc->getMetaData( 'robots' ) ) { if ( stripos( $robots, 'noindex' ) !== false ) { $this->noindex = true; } } $ctx_option = $app->input->getCmd( 'option', '' ); $ctx_view = $app->input->getCmd( 'view', '' ); $ctx = $ctx_option . '.' . $ctx_view; if ( $ctx == 'com_sppagebuilder.form' ) { return; } $c_url = null; foreach ( $doc->_links as $url => $attr ) { if ( $attr[ 'relation' ] === 'canonical' ) { $c_url = $url; unset( $doc->_links[ $url ] ); } } if ( is_null( $c_url ) && isset( $doc->_custom ) ) { foreach ( $doc->_custom as $i => $tag ) { if ( preg_match( '#rel=["\']?canonical["\']?#', $tag ) ) { if ( preg_match( '#href=(["\'])([^"\']*)\1#', $tag, $m ) ) { $c_url = htmlspecialchars_decode( trim( $m[ 2 ] ) ); unset( $doc->_custom[ $i ] ); } elseif ( preg_match( '#href=(\S+)#', $tag, $m ) ) { $c_url = htmlspecialchars_decode( trim( $m[ 1 ] ) ); unset( $doc->_custom[ $i ] ); } } } } if ( $sef_on ) { if ( $this->params->get( 'use_docbase', false ) || ( $ctx_option == 'com_virtuemart' && ( ! $c_url || strpos( $c_url, '?' ) !== false ) ) ) { $base = $doc->getBase(); if ( ! empty( $base ) ) { $c_url = $base; } } } $cur_url = Uri::getInstance()->toString(); $uri = new Uri( empty( $c_url ) ? $cur_url : $c_url ); $uri->setHost( self::fix_domain_input( $domain ) ); if ( ! empty( $proto ) ) { $uri->setScheme( $proto ); } if ( strVal( $uri->getQuery() ) == "" && ! empty( $_SERVER[ 'QUERY_STRING' ] ) ) { $uri->setQuery( $_SERVER[ 'QUERY_STRING' ] ); } if ( $sef_on && preg_match( '#/index\.php$#', $uri->getPath() ) && strpos( $uri->getQuery(), 'option=' ) !== false ) { $mpath = self::get_path_by_menu( $uri ); if ( $mpath ) { $uri->setPath( $mpath ); $uri->setQuery( '' ); } } if ( $sef_on ) { $spec = false; $needs_Itemid = false; if ( $ctx == 'com_content.article' ) { $spec = array( 'table' => 'content', 'fields' => array( 'id', 'alias', 'catid', 'language' ) ); } elseif ( $ctx == 'com_content.category' ) { $spec = array( 'table' => 'categories', 'fields' => array( 'id', 'alias', 'language' ) ); } elseif ( $ctx == 'com_tags.tag' ) { $spec = array( 'table' => 'tags', 'fields' => array( 'id', 'alias', 'language' ) ); $needs_Itemid = true; } if ( $spec ) { $o = self::get_db_object_by_id( $app->input->getUint( 'id', 0 ), $spec[ 'table' ], $spec[ 'fields' ] ); if ( ! empty( $o ) && isset( $o->id ) ) { $nsef = 'index.php?' . 'option=' . $ctx_option . '&' . 'view=' . $ctx_view . '&' . 'id=' . $o->id . ':' . $o->alias; $menu_id = self::get_menu_id_by_query( 'option=' . $ctx_option . '&view=' . $ctx_view . '&id=' . $o->id ); if ( $menu_id ) { $nsef .= '&itemid=' . $menu_id; } else { if ( $needs_Itemid ) { $Itemid = $app->input->get( 'Itemid', 0, 'int' ); if ( $Itemid && ! self::is_home_menu_item( $Itemid ) ) { $nsef .= '&Itemid=' . $Itemid; } } } if ( ! empty( $o->language ) && $o->language !== '*' ) { $nsef .= '&lang=' . $o->language; } if ( ! empty( $o->catid ) ) { $nsef .= '&catid=' . $o->catid; } $sef_url = Route::_( $nsef ); if ( $ctx == 'com_tags.tag' && preg_match( '#\?Itemid=\d+$#', $sef_url, $m ) ) { $sef_url = str_replace( $m[0], '', $sef_url ); } if ( $menu_id && preg_match( '#\?itemid=\d+$#', $sef_url, $m ) ) { $sef_url = str_replace( $m[0], '', $sef_url ); } if ( strpos( $sef_url, '?' ) === false ) { $uri->setQuery( '' ); $uri->setPath( $sef_url ); } if ( ! empty( $_SERVER[ 'QUERY_STRING' ] ) ) { $out = array( 'id', 'catid', 'option', 'view', 'task', 'itemid', 'Itemid', 'rCH' ); parse_str( $_SERVER[ 'QUERY_STRING' ], $qsps ); if ( is_array( $qsps ) && ! empty( $qsps ) ) { $keep = array(); foreach ( $qsps as $k => $v ) { if ( ! in_array( $k, $out ) ) { $keep[ $k ] = $v; } } if ( ! empty( $keep ) ) { $uri->setQuery( http_build_query( $keep ) ); } } } } } } if ( strpos( $uri->getPath(), '/' ) !== 0 ) { $uri->setPath( '/' . $uri->getPath() ); } if ( $sef_on && $this->params->get( 'remove_query_string', false ) ) { $uri->setQuery( '' ); if ( $this->params->get( 'add_pagination_qs', false ) ) { $start = $app->input->get( 'start', 0, 'int' ) ?: $app->input->get( 'limitstart', 0, 'int' ); if ( $start > 0 ) { $uri->setQuery( 'start=' . $start ); } } if ( $this->params->get( 'add_search_qs', false ) ) { $qs = array(); if ( $ctx == 'com_finder.search' ) { $q = $app->input->get( 'q', false, 'string' ); if ( ! empty( $q ) ) { $qs[] = 'q=' . $q; } $t = $app->input->get( 't', false ); if ( ! empty( $t ) && is_array( $t ) ) { foreach ( $t as $ti ) { $qs[] = 't[]=' . $ti; } } } if ( ! empty( $qs ) ) { $uri->setQuery( implode( '&', $qs ) ); } } } if ( $sef_on && ! version_compare( JVERSION, '3.5', '<' ) && $uri->getQuery() == '' && preg_match( '#/index\.php/*$#', $uri->getPath() ) ) { $uri->setPath( preg_replace( '#/index\.php/*$#', '/', $uri->getPath() ) ); } if ( $sef_on ) { $ts = $this->params->get( 'trailing_slashes', self::TRAILING_SLASHES_AS_IS ); $p = $uri->getPath(); $r = Uri::root( true ) . '/'; if ( $ts == self::TRAILING_SLASHES_REMOVE ) { if ( $p != $r && substr( $p, -1, 1 ) == '/' ) { $p = preg_replace( '#/+$#', '', $p ); } } if ( self::get_joomla_config( 'sef_suffix', false ) ) { if ( ! preg_match( '#(?:/|\.html|\.php)$#', $p ) && ! self::is_language_prefix_path( $p ) ) { $p .= '.html'; } } else { if ( $ts == self::TRAILING_SLASHES_ADD ) { if ( $p != $r && substr( $p, -1, 1 ) != '/' ) { $p .= '/'; } } } $uri->setPath( $p ); } if ( $sef_on && $this->params->get( 'remove_index_php', false ) && self::get_joomla_config( 'sef_rewrite', false ) ) { $root = trim( strVal( Uri::root( true ) ), '/' ); $p_cur = $uri->getPath(); $p_new = preg_replace( '#^/?(\Q' . $root . '\E)/index\.php/#', '/$1/', $p_cur ); $p_new = '/' . ltrim( $p_new, '/' ); if ( $p_cur != $p_new ) { $uri->setPath( $p_new ); } } if ( $sef_on && ( $case = $this->params->get( 'convert_case', 0 ) ) ) { $path = $uri->getPath(); if ( $case == 1 ) { $path = function_exists( 'mb_strtolower' ) ? mb_strtolower( $path ) : strtolower( $path ); } elseif ( $case == 2 ) { $path = function_exists( 'mb_strtoupper' ) ? mb_strtoupper( $path ) : strtoupper( $path ); } $uri->setPath( $path ); } if ( $sef_on && $this->params->get( 'custom_urls', false ) ) { $id = $app->input->get( 'id', 0, 'INT' ); if ( is_array( $id ) && ! empty( $id ) && isset( $id[ 0 ] ) ) { $id = $id[ 0 ]; } $cdata = $this->get_custom_canonical_data( $ctx, $id ); if ( isset( $cdata[ 'path' ] ) && $cdata[ 'path' ] ) { $uri->setPath( $cdata[ 'path' ] ); $uri->setQuery( '' ); } if ( isset( $cdata[ 'override' ] ) && $cdata[ 'override' ] ) { if ( isset( $cdata[ 'protocol' ] ) && $cdata[ 'protocol' ] ) { $uri->setScheme( $cdata[ 'protocol' ] ); } if ( isset( $cdata[ 'domain' ] ) && $cdata[ 'domain' ] ) { $uri->setHost( $cdata[ 'domain' ] ); } } } $url = self::juri_to_url_obj( $uri ); if ( ! empty( $url->query ) ) { $do_cleanup = $this->params->get( 'cleanup_query_string' ); parse_str( $url->query, $qparts ); if ( $do_cleanup ) { ksort( $qparts, SORT_STRING ); } $qs = http_build_query( $qparts ); if ( $do_cleanup ) { $qs = preg_replace( '#=$#', '', preg_replace( '#=&#', '&', $qs ) ); } $url->query = $qs; } if ( $this->params->get( 'redirect', false ) ) { $cur = self::juri_to_url_obj( new Uri( $cur_url ) ); if ( $this->params->get( 'redirect_on_proto', false ) && $cur->scheme != $url->scheme ) { $cur->scheme = $url->scheme; } if ( $this->params->get( 'redirect_on_domain', false ) && $cur->host != $url->host ) { $cur->host = $url->host; } if ( $this->params->get( 'redirect_on_path', false ) && $cur->path != $url->path ) { $cur->path = $url->path; } if ( $this->params->get( 'redirect_on_query_string', false ) && $cur->query != $url->query ) { $cur->query = $url->query; } $redirect_url = self::url_obj_to_string( $cur, true ); if ( $redirect_url != $cur_url ) { Factory::getApplication()->redirect( $redirect_url, 301 ); } } $canonical = self::url_obj_to_string( $url, true ); if ( ! $this->noindex ) { $doc->addCustomTag( sprintf( '<link rel="canonical" href="%s" />', htmlspecialchars( $canonical, ENT_COMPAT, 'UTF-8', false ) ) ); } $this->href = $canonical; } public function onAfterRender() { if ( ! $this->params->get( 'cleanup_head', false ) && ! $this->noindex ) { return; } $app = Factory::getApplication(); if ( ! self::in_frontend() ) { return; } $doc = Factory::getDocument(); if ( $doc->getType() !== 'html' ) { return; } $html = $app->getBody(); if ( ! is_string( $html ) or empty( $html ) ) { return false; } if ( preg_match( '#(<head[^>]*>)(.*?)(</head>)#si', $html, $m ) ) { $h = preg_replace( '#<link[^>]+?rel=["\']?canonical["\'][^>]+?/?>\s*#si', '', $m[2] ); if ( $this->noindex ) { $html = str_replace( $m[0], sprintf( "%s\n%s\n%s\n", trim( $m[1] ), trim( $h ), trim( $m[3] ) ), $html ); } else { $html = str_replace( $m[0], sprintf( "%s\n%s\n%s\n%s\n", trim( $m[1] ), trim( $h ), sprintf( '<link rel="canonical" href="%s" />', htmlspecialchars( $this->href, ENT_COMPAT, 'UTF-8', false ) ), trim( $m[3] ) ), $html ); } $app->setBody( $html ); } } private function get_custom_canonical_data( $ctx, $id ) { $app = Factory::getApplication(); $menu = $app->getMenu(); $cdata = array( 'path' => false, 'override' => false, 'protocol' => false, 'domain' => false ); if ( is_object( $menu ) ) { $mitem = $menu->getActive(); if ( is_object( $mitem ) && isset( $mitem->link ) ) { $ca = explode( '.', $ctx, 2 ); if ( count( $ca ) == 2 && strpos( $mitem->link, 'option=' . $ca[ 0 ] ) !== false && strpos( $mitem->link, 'view=' . $ca[ 1 ] ) !== false ) { $linked_id = false; if ( preg_match( '#id(?:\[0\])?=(\d+)#', $mitem->link, $m ) ) { $linked_id = $m[ 1 ]; } if ( ! $id or ( $linked_id && $linked_id == $id ) ) { $mitem_params = null; if ( method_exists( $mitem, 'getParams' ) ) { $mitem_params = $mitem->getParams(); } else if ( is_object( $mitem->params ) ) { $mitem_params = $mitem->params; } if ( is_object( $mitem_params ) ) { $cdata[ 'path' ] = $mitem_params->get( 'aimy_cncl_cpath', false ); $cdata[ 'override' ] = $mitem_params->get( 'aimy_cncl_override', false ); $cdata[ 'protocol' ] = $mitem_params->get( 'aimy_cncl_cprotocol', false ); $cdata[ 'domain' ] = $mitem_params->get( 'aimy_cncl_cdomain', false ); } } } } } $d = false; if ( $ctx == 'com_content.article' && $id > 0 ) { $o = self::get_db_object_by_id( $id, 'content', array( 'attribs' ) ); if ( is_object( $o ) ) { $d = json_decode( $o->attribs ); } } else if ( $ctx == 'com_tags.tag' && $id > 0 ) { $o = self::get_db_object_by_id( $id, 'tags', array( 'params' ) ); if ( is_object( $o ) ) { $d = json_decode( $o->params ); } } else if ( $ctx == 'com_content.category' && $id > 0 ) { $o = self::get_db_object_by_id( $id, 'categories', array( 'params' ) ); if ( is_object( $o ) ) { $d = json_decode( $o->params ); } } if ( $d && is_object( $d ) ) { if ( ! $cdata[ 'path' ] && isset( $d->aimy_cncl_cpath ) ) { $cdata[ 'path' ] = $d->aimy_cncl_cpath; } if ( ! $cdata[ 'override' ] && isset( $d->aimy_cncl_override ) ) { $cdata[ 'override' ] = $d->aimy_cncl_override; } if ( ! $cdata[ 'protocol' ] && isset( $d->aimy_cncl_cprotocol ) ) { $cdata[ 'protocol' ] = $d->aimy_cncl_cprotocol; } if ( ! $cdata[ 'domain' ] && isset( $d->aimy_cncl_cdomain ) ) { $cdata[ 'domain' ] = $d->aimy_cncl_cdomain; } } if ( isset( $cdata[ 'path' ] ) && $cdata[ 'path' ] ) { $v = self::fix_path_input( $cdata[ 'path' ] ); if ( ! empty( $v ) ) { $cdata[ 'path' ] = $v; } } if ( isset( $cdata[ 'domain' ] ) && $cdata[ 'domain' ] ) { $v = self::fix_domain_input( $cdata[ 'domain' ] ); if ( ! empty( $v ) ) { $cdata[ 'domain' ] = $v; } } return $cdata; } public function onContentPrepareForm( $form, $data ) { if ( ! $this->params->get( 'custom_urls', false ) ) { return true; } $ctx = $form->getName(); $file = false; if ( $ctx == 'com_content.article' ) { $file = 'generic-attribs'; } else if ( $ctx == 'com_categories.categorycom_content' or $ctx == 'com_menus.item' or $ctx == 'com_tags.tag' ) { $file = 'generic-params'; } if ( $file ) { Factory::getLanguage()->load( 'plg_system_aimycanonical', JPATH_ADMINISTRATOR ); $form->addFormPath( __DIR__ . '/forms/' ); $form->loadFile( $file ); if ( strpos( strVal( JVERSION ), '3.' ) !== 0 ) { Factory::getDocument()->addScriptDeclaration( 'function aimycanonicalParents(el, sel)' . '{' . 'var ps = [];' . 'while ((el = el.parentNode) && el !== document)' . '{' . 'if (!sel || el.matches(sel))' . '{' . 'ps.push(el);' . '}' . '}' . 'return ps;' . '}' . 'document.addEventListener(' . '"DOMContentLoaded",function()' . '{' . 'var el = document.querySelector(' . '".aimycanonical-intro"' . ');' . 'if (el)' . '{' . 'var ps = aimycanonicalParents(' . 'el,' . '".control-group"' . ');' . 'if (ps.length)' . '{' . 'ps[0].className = "";' . '}' . '}' . '});' ); } } if ( $ctx == 'com_menus.item' ) { HTMLHelper::_( 'jquery.framework' ); Factory::getDocument()->addScriptDeclaration( 'jQuery(document).ready(function($)' . '{' . 'function handleMenuType()' . '{' . 'var mt = $("input[name=\'jform[type]\']").val();' . 'if (!mt){return;}' . 'if (mt == "alias" || mt == "heading" || ' . 'mt == "separator" || mt == "url")' . '{' . '$("#jform_params_aimy_cncl_override0")' . '.trigger("click");' . '$("#jform_params_aimy_cncl_cpath,' . '#jform_params_aimy_cncl_cdomain")' . '.attr("disabled", "disabled")' . '.val("");' . '$("input[name=\'jform[params]' . '[aimy_cncl_override]\'],' . 'input[name=\'jform[params]' . '[aimy_cncl_cprotocol]\'],' . '#jform_params_aimy_cncl_override")' . '.attr("disabled", "disabled");' . '}' . '}' . '$("#jform_type").change(handleMenuType);' . 'handleMenuType();' . '});' ); } return true; } static private function fix_domain_input( $domain ) { return preg_replace( '/\/.*$/', '', preg_replace( '/^[^\/]*?:\/\/+/', '', trim( $domain ) ) ); } static private function get_joomla_config( $key, $dflt = null ) { $app = Factory::getApplication(); if ( version_compare( JVERSION, '3.3.0', '<' ) ) { return $app->getCfg( $key, $dflt ); } else { return $app->get( $key, $dflt ); } } static private function fix_path_input( $path ) { $path = preg_replace( '#^https?://[^/]+(/+)#i', '$1', preg_replace( '#[\?\#].*$#', '', trim( $path ) ) ); if ( strpos( $path, '/' ) === 0 ) { $path = '/' . ltrim( $path, '/' ); } else { $base = rtrim( Uri::base( true ), '/' ); if ( self::get_joomla_config( 'sef', false ) && ! self::get_joomla_config( 'sef_rewrite', 0 ) && strpos( $path, 'index.php' ) !== 0 ) { $path = $base . '/index.php/' . $path; } else { $path = $base . '/' . $path; } } return implode( '/', array_map( 'rawurlencode', explode( '/', $path ) ) ); } static private function get_db_object_by_id( $id, $tbl, $flds ) { if ( empty( $id ) or ! is_numeric( $id ) or empty( $tbl ) or ! is_string( $tbl ) or empty( $flds ) or ! is_array( $flds ) ) { return null; } $o = null; try { $db = Factory::getDbo(); $q = $db->getQuery( true ); $q->select( $db->quoteName( $flds ) ) ->from( '#__' . $tbl ) ->where( $db->quoteName( 'id' ) . '=' . $db->quote( $id ) ); $db->setQuery( $q ); $o = $db->loadObject(); if ( ! is_object( $o ) ) { $o = null; } } catch ( Exception $e ){ } return $o; } static private function in_frontend() { $app = Factory::getApplication(); if ( strpos( strVal( JVERSION ), '3.' ) === 0 ) { return $app->isSite(); } return $app->isClient( 'site' ); } static private function get_path_by_menu( $uri ) { $menu_id = self::get_menu_id_by_query( $uri->getQuery() ); if ( ! $menu_id ) { return false; } $app = Factory::getApplication(); $menu = $app->getMenu(); $ropt = array(); if ( strpos( strVal( JVERSION ), '3.' ) === 0 ) { $ropt[ 'mode' ] = JROUTER_MODE_SEF; } if ( $menu->setActive( $menu_id ) ) { $r = JRouter::getInstance( 'site', $ropt ); return $r->build( 'index.php' . '?' . $uri->getQuery() ) ->toString(); } return false; } static private function get_menu_id_by_query( $qs ) { $lang = Factory::getLanguage()->getTag(); $qa = explode( '&', $qs ); sort( $qa ); $qa = serialize( $qa ); $rows = false; try { $db = Factory::getDbo(); $q = $db->getQuery( true ); $q->select( $db->quoteName( array( 'id', 'link' ) ) ) ->from( '#__menu' ) ->where( $db->quoteName( 'language' ) . '=' . $db->quote( '*' ) . ' OR ' . $db->quoteName( 'language' ) . '=' . $db->quote( '' ) . ' OR ' . $db->quoteName( 'language' ) . '=' . $db->quote( $lang ) ); $db->setQuery( $q ); $rows = $db->loadRowList(); } catch ( Exception $e ){ } if ( ! $rows ) { return false; } foreach ( $rows as $i => $row ) { $l = explode( '&', preg_replace( '#^index\.php\?#', '', $row[ 1 ] ) ); sort( $l ); $l = serialize( $l ); if ( $l == $qa ) { return $row[ 0 ]; } } return false; } static private function is_home_menu_item( $id ) { $o = self::get_db_object_by_id( $id, 'menu', array( 'home' ) ); if ( is_object( $o ) ) { return !! $o->home; } return false; } static private function is_language_prefix_path( $path ) { if ( empty( $path ) ) { return false; } if ( strpos( $path, Uri::base( true ) ) === 0 ) { $path = substr( $path, strlen( Uri::base( true ) ), null ); } $path = trim( $path, '/' ); if ( strpos( $path, 'index.php/' ) === 0 ) { $path = substr( $path, 10, null ); } if ( strpos( $path, '/' ) !== false ) { return false; } try { $db = Factory::getDbo(); $q = $db->getQuery( true ); $q->select( $db->quoteName( 'sef' ) ) ->from( '#__languages' ) ->where( $db->quoteName( 'sef' ) . ' = ' . $db->quote( $path ) . ' AND ' . $db->quoteName( 'published' ) . ' = 1' ); $db->setQuery( $q ); $r = $db->loadResult(); return ( ! empty( $r ) ); } catch ( Exception $e ){ } return false; } static private function encode_path( $p ) { $p = str_replace( ' ', '%20', $p ); $ps = str_split( $p ); $res = ''; foreach ( $ps as $c ) { $res .= ( ord( $c ) > 0x7f ? urlencode( $c ) : $c ); } return $res; } static private function url_obj_to_string( $uo, $encode = false ) { $s = $uo->scheme . '://' . $uo->host; if ( ! empty( $uo->port ) ) { $s .= ':' . $uo->port; } $s .= $encode ? self::encode_path( $uo->path ) : $uo->path; if ( ! empty( $uo->query ) ) { $s .= '?' . $uo->query; } return $s; } static private function juri_to_url_obj( $juri ) { $url = new StdClass(); $url->scheme = $juri->getScheme(); $url->host = $juri->getHost(); $url->port = $juri->getPort(); $url->path = $juri->getPath(); $url->query = $juri->getQuery(); return $url; } public function onExtensionAfterSave( $context, $table, $isNew, $data = array() ) { if ( strpos( JVERSION, '3.' ) !== 0 ) { return; } if ( $context != 'com_plugins.plugin' or ! is_object( $table ) or ! property_exists( $table, 'element' ) or $table->element != 'aimycanonical' ) { return; } if ( ! is_array( $data ) or empty( $data ) or ! isset( $data[ 'params' ] ) or ! is_array( $data[ 'params' ] ) or ! isset( $data[ 'params' ][ 'dl_key' ] ) ) { return; } $key = trim( $data[ 'params' ][ 'dl_key' ] ); require_once( __DIR__ . '/helpers/DownloadKeyHelper.php' ); try { AimyCanonical\Helpers\DownloadKeyHelper::passKeyToUpdatesites( $key ); } catch ( Exception $e ) { Factory::getApplication( 'Failed to pass download key to update sites: ' . $e->getMessage(), 'error' ); } } public function onInstallerBeforePackageDownload( &$url, &$headers ) { if ( ! strpos( $url, 'aimy-extensions.com' ) or ! strpos( $url, '/plg_AimyCanonical/' ) ) { return; } require_once( __DIR__ . '/helpers/DownloadKeyHelper.php' ); $rv = AimyCanonical\Helpers\DownloadKeyHelper::validateKey(); if ( is_object( $rv ) && ! $rv->valid && isset( $rv->msg ) ) { Factory::getApplication()->enqueueMessage( '<b>Aimy Canonical: ' . $rv->msg . '</b>', 'error' ); } } } 
aimycanonical.xml000064400000025147152344413770010120 0ustar00<?xml version="1.0" encoding="UTF-8"?>
<extension version="3.0" type="plugin" group="system" method="upgrade">
    <name>System - Aimy Canonical (PRO)</name>
    <creationDate>2024-10-15</creationDate>
    <author>Aimy Extensions (Netzum Sorglos Software GmbH)</author>
    <authorEmail>info@aimy-extensions.com</authorEmail>
    <authorUrl>https://www.aimy-extensions.com/</authorUrl>
    <copyright>2013-2024 Aimy Extensions, Netzum Sorglos Software GmbH</copyright>
    <license>GNU General Public License (GPL) v2</license>
    <version>29.0</version>
    <description>Canonical Link Tags for your Website (PRO)</description>
    <dlid prefix="dl_key=" suffix="" />
    <scriptfile>install-hints.php</scriptfile>
    <files>
        <filename plugin="aimycanonical">aimycanonical.php</filename>
        <filename>index.html</filename>
        <folder>fields</folder>
        <filename>helpers/DownloadKeyHelper.php</filename>
        <folder>forms</folder>
    </files>
    <media destination="plg_aimycanonical" folder="media">
        <filename>aimy-logo_340x327.png</filename>
        <filename>index.html</filename>
    </media>
    <languages>
        <language tag="de-DE">i18n/de-DE.plg_system_aimycanonical.ini</language>
        <language tag="en-GB">i18n/en-GB.plg_system_aimycanonical.ini</language>
        <language tag="es-ES">i18n/es-ES.plg_system_aimycanonical.ini</language>
        <language tag="fa-IR">i18n/fa-IR.plg_system_aimycanonical.ini</language>
        <language tag="fr-FR">i18n/fr-FR.plg_system_aimycanonical.ini</language>
        <language tag="hu-HU">i18n/hu-HU.plg_system_aimycanonical.ini</language>
        <language tag="it-IT">i18n/it-IT.plg_system_aimycanonical.ini</language>
        <language tag="nl-NL">i18n/nl-NL.plg_system_aimycanonical.ini</language>
        <language tag="pl-PL">i18n/pl-PL.plg_system_aimycanonical.ini</language>
        <language tag="pt-BR">i18n/pt-BR.plg_system_aimycanonical.ini</language>
        <language tag="sk-SK">i18n/sk-SK.plg_system_aimycanonical.ini</language>
        <language tag="sl-SI">i18n/sl-SI.plg_system_aimycanonical.ini</language>
        <language tag="bg-BG">i18n/bg-BG.plg_system_aimycanonical.ini</language>
        <language tag="prs-AF">i18n/prs-AF.plg_system_aimycanonical.ini</language>
        <language tag="th-TH">i18n/th-TH.plg_system_aimycanonical.ini</language>
        <language tag="ro-RO">i18n/ro-RO.plg_system_aimycanonical.ini</language>
        <language tag="ru-RU">i18n/ru-RU.plg_system_aimycanonical.ini</language>
        <language tag="cs-CZ">i18n/cs-CZ.plg_system_aimycanonical.ini</language>
    </languages>
    <config>
      <fields name="params"
        addfieldpath="/plugins/system/aimycanonical/fields/">
        <fieldset name="basic">
          <field name="domain" type="text" default=""
            class="inputbox"
            required="true"
            label="AIMY_CNCL_DOMAIN_LBL"
            description="AIMY_CNCL_DOMAIN_DSC" />
          <field name="protocol"
            type="radio" default="http"
            class="btn-group btn-group-yesno"
            required="true"
            labelclass="control-group"
            label="AIMY_CNCL_PROTOCOL_LBL"
            description="AIMY_CNCL_PROTOCOL_DSC">
              <option value="http">http</option>
              <option value="https">https</option>
          </field>
          <field type="spacer" hr="true" />
          <field name="remove_query_string"
            type="radio" default="0"
            class="btn-group btn-group-yesno"
            labelclass="control-group"
            label="AIMY_CNCL_REMOVE_QUERY_STRING_LBL"
            description="AIMY_CNCL_REMOVE_QUERY_STRING_DSC">
              <option value="1">JYES</option>
              <option value="0">JNO</option>
          </field>
          <field name="add_pagination_qs"
            type="radio" default="0"
            class="btn-group btn-group-yesno aimy-pro-feature"
            labelclass="control-group"
            showon="remove_query_string:1"
            label="AIMY_CNCL_ADD_PAGINATION_QS_LBL"
            description="AIMY_CNCL_ADD_PAGINATION_QS_DSC">
              <option value="1">JYES</option>
              <option value="0">JNO</option>
          </field>
          <field name="add_search_qs"
            type="radio" default="0"
            class="btn-group btn-group-yesno aimy-pro-feature"
            labelclass="control-group"
            showon="remove_query_string:1"
            label="AIMY_CNCL_ADD_SEARCH_QS_LBL"
            description="AIMY_CNCL_ADD_SEARCH_QS_DSC">
              <option value="1">JYES</option>
              <option value="0">JNO</option>
          </field>
          <field name="cleanup_query_string"
            type="radio" default="0"
            class="btn-group btn-group-yesno aimy-pro-feature"
            labelclass="control-group"
            showon="remove_query_string:0"
            label="AIMY_CNCL_CLEANUP_QUERY_STRING_LBL"
            description="AIMY_CNCL_CLEANUP_QUERY_STRING_DSC">
              <option value="1">JYES</option>
              <option value="0">JNO</option>
          </field>
          <field type="spacer" hr="true" />
          <field name="remove_index_php"
            type="radio" default="0"
            class="btn-group btn-group-yesno aimy-pro-feature"
            labelclass="control-group"
            label="AIMY_CNCL_REMOVE_INDEX_PHP_LBL"
            description="AIMY_CNCL_REMOVE_INDEX_PHP_DSC">
              <option value="1">JYES</option>
              <option value="0">JNO</option>
          </field>
          <field name="cleanup_head"
            type="radio" default="0"
            class="btn-group btn-group-yesno aimy-pro-feature"
            labelclass="control-group"
            label="AIMY_CNCL_CLEANUP_HEAD_LBL"
            description="AIMY_CNCL_CLEANUP_HEAD_DSC">
              <option value="1">JYES</option>
              <option value="0">JNO</option>
          </field>
          <field name="use_docbase"
            type="radio" default="0"
            class="btn-group btn-group-yesno aimy-pro-feature"
            labelclass="control-group"
            label="AIMY_CNCL_USE_DOCBASE_LBL"
            description="AIMY_CNCL_USE_DOCBASE_DSC">
              <option value="1">JYES</option>
              <option value="0">JNO</option>
          </field>
          <field name="trailing_slashes"
            type="radio" default="0"
            class="btn-group aimy-pro-feature"
            labelclass="control-group"
            label="AIMY_CNCL_TRAILING_SLASHES_LBL"
            description="AIMY_CNCL_TRAILING_SLASHES_DSC">
                <option value="0">AIMY_CNCL_TRAILING_SLASHES_AS_IS</option>
                <option value="1">AIMY_CNCL_TRAILING_SLASHES_REMOVE</option>
                <option value="2">AIMY_CNCL_TRAILING_SLASHES_ADD</option>
          </field>
          <field name="convert_case"
            type="radio" default="0"
            class="btn-group aimy-pro-feature"
            labelclass="control-group"
            label="AIMY_CNCL_CONVERT_CASE_LBL"
            description="AIMY_CNCL_CONVERT_CASE_DSC">
                <option value="0">AIMY_CNCL_CONVERT_CASE_KEEP</option>
                <option value="1">AIMY_CNCL_CONVERT_CASE_LOWERCASE</option>
                <option value="2">AIMY_CNCL_CONVERT_CASE_UPPERCASE</option>
          </field>
          <field name="custom_urls"
            type="radio" class="btn-group btn-group-yesno aimy-pro-feature"
            default="1"
            labelclass="control-group"
            label="AIMY_CNCL_CUSTOM_URLS_LBL"
            description="AIMY_CNCL_CUSTOM_URLS_DSC">
                <option value="1">JYES</option>
                <option value="0">JNO</option>
          </field>
        </fieldset>
        <fieldset name="redirects" label="AIMY_CNCL_REDIRECTS_LBL">
          <field name="redirect"
            type="radio" default="0"
            class="btn-group btn-group-yesno aimy-pro-feature"
            labelclass="control-group"
            label="AIMY_CNCL_REDIRECT_LBL"
            description="AIMY_CNCL_REDIRECT_DSC">
              <option value="1">JYES</option>
              <option value="0">JNO</option>
          </field>
          <field name="redirect_on_proto"
            type="radio" default="1"
            class="btn-group btn-group-yesno aimy-pro-feature"
            labelclass="control-group"
            showon="redirect:1"
            label="AIMY_CNCL_REDIRECT_ON_PROTO_LBL"
            description="AIMY_CNCL_REDIRECT_ON_PROTO_DSC">
              <option value="1">JYES</option>
              <option value="0">JNO</option>
          </field>
          <field name="redirect_on_domain"
            type="radio" default="1"
            class="btn-group btn-group-yesno aimy-pro-feature"
            labelclass="control-group"
            showon="redirect:1"
            label="AIMY_CNCL_REDIRECT_ON_DOMAIN_LBL"
            description="AIMY_CNCL_REDIRECT_ON_DOMAIN_DSC">
              <option value="1">JYES</option>
              <option value="0">JNO</option>
          </field>
          <field name="redirect_on_path"
            type="radio" default="0"
            class="btn-group btn-group-yesno aimy-pro-feature"
            labelclass="control-group"
            showon="redirect:1"
            label="AIMY_CNCL_REDIRECT_ON_PATH_LBL"
            description="AIMY_CNCL_REDIRECT_ON_PATH_DSC">
              <option value="1">JYES</option>
              <option value="0">JNO</option>
          </field>
          <field name="redirect_on_query_string"
            type="radio" default="0"
            class="btn-group btn-group-yesno aimy-pro-feature"
            labelclass="control-group"
            showon="redirect:1"
            label="AIMY_CNCL_REDIRECT_ON_QUERY_STRING_LBL"
            description="AIMY_CNCL_REDIRECT_ON_QUERY_STRING_DSC">
              <option value="1">JYES</option>
              <option value="0">JNO</option>
          </field>
          <field name="redirect_warning"
            type="spacer"
            label="AIMY_CNCL_REDIRECT_ALL_DISABLED_WARNING_LBL"
            class="alert alert-danger btn-group"
            showon="redirect:1[AND]redirect_on_proto:0[AND]redirect_on_domain:0[AND]redirect_on_path:0[AND]redirect_on_query_string:0" />
        </fieldset>
        <fieldset name="key" label="AIMY_CNCL_KEY_TAB_LBL">
          <field name="dl_key" type="aimydownloadkey" default=""
            class="inputbox"
            required="false"
            filter="cmd"
            label="AIMY_CNCL_DL_KEY_LBL" />
        </fieldset>
      </fields>
    </config>
    <updateservers>
      <server
        type="extension"
        priority="1"
        name="Aimy Canonical PRO Update Server">http://updates.aimy-extensions.com/joomla/plg_aimycanonical-pro.xml</server>
    </updateservers>
</extension>
index.html000064400000000016152344413770006550 0ustar00<html></html>
install-hints.php000064400000011650152344413770010063 0ustar00<?php
/*
 * Copyright (c) 2017-2024 Aimy Extensions, Netzum Sorglos Software GmbH
 * Copyright (c) 2014-2017 Aimy Extensions, Lingua-Systems Software GmbH
 *
 * https://www.aimy-extensions.com/
 *
 *
 * License: GNU GPLv2, see LICENSE.txt within distribution and/or
 *          http://www.aimy-extensions.com/software-license.html
 */
 defined( '_JEXEC' ) or die(); use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\Uri\Uri; use Joomla\CMS\Router\Route; use Joomla\CMS\Filesystem\File; use Joomla\Registry\Registry; class plgSystemAimyCanonicalInstallerScript { const V_JOOMLA_MIN = '3.9'; const V_PHP_MIN = '5.3.10'; public function preflight( $type, $parent ) { return ( self::check_php_version( self::V_PHP_MIN ) && self::check_joomla_version( self::V_JOOMLA_MIN ) ); } public function postflight( $route, $adapter ) { $task = strtolower( $route ); if ( $task != 'install' && $task != 'update' ) { return; } if ( $task == 'update' ) { require( __DIR__ . '/helpers/UpdateServer.php' ); AimyCanonicalUpdateServer::cleanup_server_list( $adapter ); require( __DIR__ . '/helpers/UpdateParams.php' ); AimyCanonicalUpdateParams::rename_param( 'custom_paths', 'custom_urls' ); $files_to_remove = array( 'proonlynotice.php' ); foreach ( $files_to_remove as $file ) { $path = JPATH_ROOT . '/plugins/system/aimycanonical/' . $file; if ( file_exists( $path ) ) { File::delete( $path ); } } if ( strpos( JVERSION, '3.' ) !== 0 ) { try { self::deleteExtensionParam( 'dl_key' ); } catch ( Exception $e ) { error_log( 'AimyCanonical: ' . $e->getMessage() ); } } } if ( $task == 'install' ) { Factory::getLanguage()->load( 'plg_system_aimycanonical', JPATH_ADMINISTRATOR ); echo '<div style="padding:32px;text-align:center;">', '<h1>', '<img src="', Uri::base(), '../media/plg_aimycanonical/aimy-logo_340x327.png" ', 'width="340" height="327" alt="Aimy" />', '<br/>', 'Aimy Canonical (PRO) v29.0', '</h1>', '<p class="lead">', Text::_( $task == 'update' ? 'AIMY_CNCL_HINT_UPDATED' : 'AIMY_CNCL_HINT_INSTALLED' ), '!', '</p>'; $cfg_url = false; $enabled = false; try { $db = Factory::getDbo(); $q = $db->getQuery( true ); $q->select( $db->quoteName( array( 'extension_id', 'enabled' ) ) ) ->from( $db->quoteName( '#__extensions' ) ) ->where( $db->quoteName( 'element' ) . ' = ' . $db->quote( 'aimycanonical' ) ) ->where( $db->quoteName( 'type' ) . ' = ' . $db->quote( 'plugin' ) ); $db->setQuery( $q ); $row = $db->loadObject(); if ( $row && $row->extension_id ) { $cfg_url = Route::_( 'index.php?' . 'option=com_plugins&task=plugin.edit&' . 'extension_id=' . $row->extension_id ); $enabled = $row->enabled; } } catch ( Exception $e ) {} echo '<p>'; if ( $cfg_url ) { echo self::_btn( $cfg_url, Text::_( ! $enabled ? 'AIMY_CNCL_HINT_ENABLE_CONFIGURE' : 'AIMY_CNCL_HINT_CONFIGURE' ) ), ' &nbsp; '; } echo self::_btn( 'https://www.aimy-extensions.com/joomla/canonical.html#user-manual', Text::_( 'AIMY_CNCL_HINT_READ_MANUAL' ), true ), ' &nbsp; ', self::_btn( 'https://aimy-extensions.com/images/products/canonical/plg-aimy-canonical.pdf?v=29.0', Text::_( 'AIMY_CNCL_HINT_DL_MANUAL' ), false ), '</p>'; echo '<p style="padding:12px 0;" />', '<a href="https://www.aimy-extensions.com/joomla/canonical.html" target="_blank">https://www.aimy-extensions.com/joomla/canonical.html</a>', '</p>', '</div>', "\n"; } } static private function _btn( $url, $text, $new_tab = false ) { return '<a class="btn btn-lg btn-success" href="' . $url . '" ' . ( $new_tab ? 'target="_blank" ' : '' ) . 'role="button" style="color:#FFF !important">' . $text . '!' . '</a>'; } static private function check_php_version( $min ) { if ( version_compare( PHP_VERSION, $min, '<' ) ) { Factory::getApplication()->enqueueMessage( 'You are currently using PHP ' . PHP_VERSION . ', ' . 'but Aimy Canonical requires at least PHP ' . $min . '.', 'error' ); return false; } return true; } static private function check_joomla_version( $min ) { $jv = defined( 'JVERSION' ) ? JVERSION : 0; if ( version_compare( $jv, $min, '<' ) ) { Factory::getApplication()->enqueueMessage( 'You are currently using Joomla! ' . $jv . ', ' . 'but Aimy Canonical requires at least Joomla! ' . $min . '.', 'error' ); return false; } return true; } static private function deleteExtensionParam( $name ) { $element = ( 'plg' == 'com' ? 'com_' : '' ) . 'aimycanonical'; $db = Factory::getDbo(); $q = $db->getQuery( true ); $q->select( $db->quoteName( 'params' ) ) ->from( $db->quoteName( '#__extensions' ) ) ->where( $db->quoteName( 'element' ) . ' = ' . $db->quote( $element ) ); $db->setQuery( $q ); $rv = $db->loadResult(); if ( empty( $rv ) ) { return false; } $params = new Registry(); $params->loadString( $rv ); if ( ! $params or ! $params->exists( $name ) ) { return false; } $params->remove( $name ); $q = $db->getQuery( true ); $q->update( $db->quoteName( '#__extensions' ) ) ->set( $db->quoteName( 'params' ) . ' = ' . $db->quote( $params->toString() ) ) ->where( $db->quoteName( 'element' ) . ' = ' . $db->quote( $element ) ); $db->setQuery( $q ); return $db->execute(); } }