From f9bcbc0d53a0a40699c7d00e2eb4d3bc58071341 Mon Sep 17 00:00:00 2001 From: Sergey Tolkachyov Date: Tue, 13 Sep 2022 13:42:05 +0400 Subject: [PATCH] v.1.0.0 --- language/en-GB/mod_wtyandexmapitems.ini | 60 +++ language/en-GB/mod_wtyandexmapitems.sys.ini | 7 + language/ru-RU/mod_wtyandexmapitems.ini | 60 +++ language/ru-RU/mod_wtyandexmapitems.sys.ini | 7 + mod_wtyandexmapitems.xml | 356 +++++++++++++++++ script.php | 264 +++++++++++++ services/provider.php | 41 ++ src/Dispatcher/Dispatcher.php | 60 +++ src/Helper/WtyandexmapitemsHelper.php | 368 ++++++++++++++++++ tmpl/default.php | 97 +++++ .../sublayouts/default_balloonContentBody.php | 51 +++ .../default_balloonContentBodyCustom.php | 51 +++ 12 files changed, 1422 insertions(+) create mode 100644 language/en-GB/mod_wtyandexmapitems.ini create mode 100644 language/en-GB/mod_wtyandexmapitems.sys.ini create mode 100644 language/ru-RU/mod_wtyandexmapitems.ini create mode 100644 language/ru-RU/mod_wtyandexmapitems.sys.ini create mode 100644 mod_wtyandexmapitems.xml create mode 100644 script.php create mode 100644 services/provider.php create mode 100644 src/Dispatcher/Dispatcher.php create mode 100644 src/Helper/WtyandexmapitemsHelper.php create mode 100644 tmpl/default.php create mode 100644 tmpl/sublayouts/default_balloonContentBody.php create mode 100644 tmpl/sublayouts/default_balloonContentBodyCustom.php diff --git a/language/en-GB/mod_wtyandexmapitems.ini b/language/en-GB/mod_wtyandexmapitems.ini new file mode 100644 index 0000000..120f359 --- /dev/null +++ b/language/en-GB/mod_wtyandexmapitems.ini @@ -0,0 +1,60 @@ +MOD_WTYANDEXMAPITEMS="WT Yandex map items" +MOD_WTYANDEXMAPITEMS_DESC="Outputs labels from various components to Yandex.Maps" +; Basic fieldset +MOD_WTYANDEXMAPITEMS_DATA_SOURCE="Data source" +MOD_WTYANDEXMAPITEMS_DATA_SOURCE_DESC="Component whose fields will be the data source for the module" +MOD_WTYANDEXMAPITEMS_DATA_GROUP_LABEL_COM_CONTENT="Joomla articles" +MOD_WTYANDEXMAPITEMS_DATA_GROUP_LABEL_COM_CONTENT_ARTICLE="articles" +MOD_WTYANDEXMAPITEMS_DATA_GROUP_LABEL_COM_CONTENT_CATEGORY="Categories" +MOD_WTYANDEXMAPITEMS_DATA_GROUP_LABEL_COM_CONTACT="Joomla Contacts" +MOD_WTYANDEXMAPITEMS_DATA_GROUP_LABEL_COM_CONTACT_CONTACT="Contacts" +MOD_WTYANDEXMAPITEMS_DATA_GROUP_LABEL_COM_CONTACT_CATEGORY="Categories" +MOD_WTYANDEXMAPITEMS_COM_CONTENT_ARTICLE_YANDEX_MAP_COORDS_FIELD_ID="Article fields" +MOD_WTYANDEXMAPITEMS_COM_CONTENT_CATEGORY_YANDEX_MAP_COORDS_FIELD_ID="Article category fields" +MOD_WTYANDEXMAPITEMS_COM_CONTACT_CONTACT_YANDEX_MAP_COORDS_FIELD_ID="Contact fields" +MOD_WTYANDEXMAPITEMS_COM_CONTACT_CATEGORY_YANDEX_MAP_COORDS_FIELD_ID="Contact category fields" +MOD_WTYANDEXMAPITEMS_BALLOONCONTENTBODY_LAYOUT="Layout of the label content output (balloonContentBody)" +MOD_WTYANDEXMAPITEMS_BALLOONCONTENTBODY_LAYOUT_DESC="Specify the output layout file. You can create your own in the image and likeness and save it in modules/mod_wtyandexmapitems/tmpl/sublayouts" +;Articles fieldset +MOD_WTYANDEXMAPITEMS_COM_CONTENT_ARTICLES_PARAMS_FIELDSET_LABEL="Articles" +MOD_WTYANDEXMAPITEMS_COM_CONTENT_ARTICLES_PARAMS_DYSPLAY_FIELDSET_LABEL="Setting the label display" +MOD_WTYANDEXMAPITEMS_COM_CONTENT_ARTICLES_PARAMS_DYSPLAY_FIELDSET_DESC="Setting up the selection of articles for placemarks. Articles must contain filled fields with coordinates of the form 51.55, 46.00" +MOD_WTYANDEXMAPITEMS_SHOW_ARTICLE_TITLE="Show the placemark title?" +MOD_WTYANDEXMAPITEMS_ARTICLE_BALOON_TEXT="The text in the placemark hint is..." +MOD_WTYANDEXMAPITEMS_ARTICLE_BALOON_TEXT_FULLTEXT="Full text" +MOD_WTYANDEXMAPITEMS_ARTICLE_BALOON_TEXT_INTROTEXT="Intro text" +MOD_WTYANDEXMAPITEMS_ARTICLE_BALOON_TEXT_TEXT_FROM_FIELD="Field text" +MOD_WTYANDEXMAPITEMS_COM_CONTENT_ARTICLE_ARTICLE_BALOON_TEXT_FROM_FIELD_FIELD_ID="Article fields" +MOD_WTYANDEXMAPITEMS_ARTICLE_IMG_INTRO_FULL="Placemark images are..." +MOD_WTYANDEXMAPITEMS_ARTICLE_IMG_INTRO_FULL_INTRO="Intro text image" +MOD_WTYANDEXMAPITEMS_ARTICLE_IMG_INTRO_FULL_FULL="Full text image" +MOD_WTYANDEXMAPITEMS_ARTICLE_IMG_INTRO_FULL_IMAGE_FROM_FIELD="Image from the field" +MOD_WTYANDEXMAPITEMS_COM_CONTENT_ARTICLE_ARTICLE_BALOON_IMAGE_FROM_FIELD_FIELD_ID="article fields" +MOD_WTYANDEXMAPITEMS_COM_CONTENT_ARTICLE_ARTICLE_BALOON_IMAGE_FROM_FIELD_FIELD_ID_LABEL="Note" +MOD_WTYANDEXMAPITEMS_COM_CONTENT_ARTICLE_ARTICLE_BALOON_IMAGE_FROM_FIELD_FIELD_ID_DESC="If the field type is a child form (subform), then the child form must contain at least one media type field. The first image from the list will be taken." +MOD_WTYANDEXMAPITEMS_SHOW_ARTICLE_READMORE="Show readmore link?" +MOD_WTYANDEXMAPITEMS_ARTICLE_COUNT="The number of displayed placemarks-articles" +MOD_WTYANDEXMAPITEMS_ARTICLE_COUNT_DESC="If you specify 0, all published articles under the specified conditions will be displayed" + +MOD_WTYANDEXMAPITEMS_COM_CONTENT_PARAMS_ARTICLES_2_FIELDSET_LABEL="Selection of articles" +MOD_WTYANDEXMAPITEMS_ARTICLE_TRIGGEREVENTS="Process content with plugins" +; Yandex map fieldset +MOD_WTYANDEXMAPITEMS_YANDEX_MAP_PARAMS_FIELDSET_LABEL="Yandex.maps" +MOD_WTYANDEXMAPITEMS_YANDEX_MAP_PARAMS_CREDENTIALS_FIELDSET_LABEL="Connection settings" +MOD_WTYANDEXMAPITEMS_YANDEX_MAP_API_KEY="Yandex.maps API key" +MOD_WTYANDEXMAPITEMS_YANDEX_API_TYPE="API type" +MOD_WTYANDEXMAPITEMS_YANDEX_API_TYPE_FREE="Free" +MOD_WTYANDEXMAPITEMS_YANDEX_API_TYPE_PAID="Paid" +MOD_WTYANDEXMAPITEMS_YANDEX_API_TYPE_DESC="Different API entry points are used for the paid and free versions" +MOD_WTYANDEXMAPITEMS_YANDEX_MAP_PARAMS_DISPLAY_FIELDSET_LABEL="Display settings" +MOD_WTYANDEXMAPITEMS_MAP_CENTER="Map center (coordinates separated by commas)" +MOD_WTYANDEXMAPITEMS_MAP_CENTER_DESC="Specify the coordinates of the center comma-separated maps, for example, 51.533562, 46.034266" +MOD_WTYANDEXMAPITEMS_MAP_ZOOM="Scale" +MOD_WTYANDEXMAPITEMS_MAP_TYPE="Map type" +MOD_WTYANDEXMAPITEMS_MAP_TYPE_MAP="Scheme" +MOD_WTYANDEXMAPITEMS_MAP_TYPE_SATELLITE="Satellite" +MOD_WTYANDEXMAPITEMS_MAP_TYPE_HYBRID="Hybrid" +MOD_WTYANDEXMAPITEMS_MAP_WIDTH="Map width" +MOD_WTYANDEXMAPITEMS_MAP_WIDTH_DESC="Specify with units of measurement, as in CSS - 500px or 100%" +MOD_WTYANDEXMAPITEMS_MAP_HEIGHT="Map height" +MOD_WTYANDEXMAPITEMS_MAP_HEIGHT_DESC="Specify with units of measurement, as in CSS - 500px or 100%" \ No newline at end of file diff --git a/language/en-GB/mod_wtyandexmapitems.sys.ini b/language/en-GB/mod_wtyandexmapitems.sys.ini new file mode 100644 index 0000000..2648a5b --- /dev/null +++ b/language/en-GB/mod_wtyandexmapitems.sys.ini @@ -0,0 +1,7 @@ +MOD_WTYANDEXMAPITEMS="WT Yandex map items" +MOD_WTYANDEXMAPITEMS_DESC="Display data from various components like Yandex.Maps placemarks" +MOD_WTYANDEXMAPITEMS_AFTER_INSTALL = "Thank you for intalling extension" +MOD_WTYANDEXMAPITEMS_AFTER_DISCOVER_INSTALL = "Thank you for intalling extension" +MOD_WTYANDEXMAPITEMS_AFTER_UPDATE = "Thank you for updating extension" +MOD_WTYANDEXMAPITEMS_MAYBE_INTERESTING="

It might be interesting

" +MOD_WTYANDEXMAPITEMS_WHATS_NEW = "

v.1.0.0 What's new?

First extension version

Joomla articles are displayed as Yandex.maps placemarks. The articles categories and contacts are not displayed yet.

" \ No newline at end of file diff --git a/language/ru-RU/mod_wtyandexmapitems.ini b/language/ru-RU/mod_wtyandexmapitems.ini new file mode 100644 index 0000000..5ff734b --- /dev/null +++ b/language/ru-RU/mod_wtyandexmapitems.ini @@ -0,0 +1,60 @@ +MOD_WTYANDEXMAPITEMS="WT Yandex map items" +MOD_WTYANDEXMAPITEMS_DESC="Выводит метки из различных компонентов на Яндекс.Карты" +; Basic fieldset +MOD_WTYANDEXMAPITEMS_DATA_SOURCE="Источник данных" +MOD_WTYANDEXMAPITEMS_DATA_SOURCE_DESC="Компонент, чьи поля будут источником данных для модуля" +MOD_WTYANDEXMAPITEMS_DATA_GROUP_LABEL_COM_CONTENT="Материалы Joomla" +MOD_WTYANDEXMAPITEMS_DATA_GROUP_LABEL_COM_CONTENT_ARTICLE="Материалы" +MOD_WTYANDEXMAPITEMS_DATA_GROUP_LABEL_COM_CONTENT_CATEGORY="Категории" +MOD_WTYANDEXMAPITEMS_DATA_GROUP_LABEL_COM_CONTACT="Контакты Joomla" +MOD_WTYANDEXMAPITEMS_DATA_GROUP_LABEL_COM_CONTACT_CONTACT="Контакты" +MOD_WTYANDEXMAPITEMS_DATA_GROUP_LABEL_COM_CONTACT_CATEGORY="Категории" +MOD_WTYANDEXMAPITEMS_COM_CONTENT_ARTICLE_YANDEX_MAP_COORDS_FIELD_ID="Поля материалов" +MOD_WTYANDEXMAPITEMS_COM_CONTENT_CATEGORY_YANDEX_MAP_COORDS_FIELD_ID="Поля категорий материалов" +MOD_WTYANDEXMAPITEMS_COM_CONTACT_CONTACT_YANDEX_MAP_COORDS_FIELD_ID="Поля контактов" +MOD_WTYANDEXMAPITEMS_COM_CONTACT_CATEGORY_YANDEX_MAP_COORDS_FIELD_ID="Поля категорий контактов" +MOD_WTYANDEXMAPITEMS_BALLOONCONTENTBODY_LAYOUT="Макет вывода содержимого метки (balloonContentBody)" +MOD_WTYANDEXMAPITEMS_BALLOONCONTENTBODY_LAYOUT_DESC="Укажите файл макета вывода. Вы можете создать свой собственный по образу и подобию и сохранить его в modules/mod_wtyandexmapitems/tmpl/sublayouts" +; Articles fieldset +MOD_WTYANDEXMAPITEMS_COM_CONTENT_ARTICLES_PARAMS_FIELDSET_LABEL="Материалы" +MOD_WTYANDEXMAPITEMS_COM_CONTENT_ARTICLES_PARAMS_DYSPLAY_FIELDSET_LABEL="Настройка отображения метки" +MOD_WTYANDEXMAPITEMS_COM_CONTENT_ARTICLES_PARAMS_DYSPLAY_FIELDSET_DESC="Настройка выборки материалов для меток. Материалы должны содержать заполненные поля с координатами вида 51.55, 46.00" +MOD_WTYANDEXMAPITEMS_SHOW_ARTICLE_TITLE="Показывать заголовок метки?" +MOD_WTYANDEXMAPITEMS_ARTICLE_BALOON_TEXT="Текст в подсказке метки это..." +MOD_WTYANDEXMAPITEMS_ARTICLE_BALOON_TEXT_FULLTEXT="Полный текст" +MOD_WTYANDEXMAPITEMS_ARTICLE_BALOON_TEXT_INTROTEXT="Вступительный текст" +MOD_WTYANDEXMAPITEMS_ARTICLE_BALOON_TEXT_TEXT_FROM_FIELD="Текст поля" +MOD_WTYANDEXMAPITEMS_COM_CONTENT_ARTICLE_ARTICLE_BALOON_TEXT_FROM_FIELD_FIELD_ID="Поля материалов" +MOD_WTYANDEXMAPITEMS_ARTICLE_IMG_INTRO_FULL="Изображения метки это..." +MOD_WTYANDEXMAPITEMS_ARTICLE_IMG_INTRO_FULL_INTRO="Изображение вступительного текста" +MOD_WTYANDEXMAPITEMS_ARTICLE_IMG_INTRO_FULL_FULL="Изображение полного текста" +MOD_WTYANDEXMAPITEMS_ARTICLE_IMG_INTRO_FULL_IMAGE_FROM_FIELD="Изображение из поля" +MOD_WTYANDEXMAPITEMS_COM_CONTENT_ARTICLE_ARTICLE_BALOON_IMAGE_FROM_FIELD_FIELD_ID="Поля материалов" +MOD_WTYANDEXMAPITEMS_COM_CONTENT_ARTICLE_ARTICLE_BALOON_IMAGE_FROM_FIELD_FIELD_ID_LABEL="Обратите внимание" +MOD_WTYANDEXMAPITEMS_COM_CONTENT_ARTICLE_ARTICLE_BALOON_IMAGE_FROM_FIELD_FIELD_ID_DESC="Если тип поля - дочерняя форма (subform), то дочерняя форма должна содержать хотя бы одно поле типа media. Будет взято первое изображение из списка." +MOD_WTYANDEXMAPITEMS_SHOW_ARTICLE_READMORE="Показывать ссылку Подробнее?" +MOD_WTYANDEXMAPITEMS_ARTICLE_COUNT="Количество отображаемых меток-материалов" +MOD_WTYANDEXMAPITEMS_ARTICLE_COUNT_DESC="Если указать 0, то будут отображаться все опубликованные материалы по указанным условиям" + +MOD_WTYANDEXMAPITEMS_COM_CONTENT_PARAMS_ARTICLES_2_FIELDSET_LABEL="Выборка материалов" +MOD_WTYANDEXMAPITEMS_ARTICLE_TRIGGEREVENTS="Обрабатывать контент-плагинами" +; Yandex map fieldset +MOD_WTYANDEXMAPITEMS_YANDEX_MAP_PARAMS_FIELDSET_LABEL="Яндекс.карты" +MOD_WTYANDEXMAPITEMS_YANDEX_MAP_PARAMS_CREDENTIALS_FIELDSET_LABEL="Настройки подключения" +MOD_WTYANDEXMAPITEMS_YANDEX_MAP_API_KEY="API-ключ Яндекс.карт" +MOD_WTYANDEXMAPITEMS_YANDEX_API_TYPE="Тип API" +MOD_WTYANDEXMAPITEMS_YANDEX_API_TYPE_FREE="Бесплатный" +MOD_WTYANDEXMAPITEMS_YANDEX_API_TYPE_PAID="Платный" +MOD_WTYANDEXMAPITEMS_YANDEX_API_TYPE_DESC="Для платной и бесплатной версии используются разные точки входа API" +MOD_WTYANDEXMAPITEMS_YANDEX_MAP_PARAMS_DISPLAY_FIELDSET_LABEL="Настройки отображения" +MOD_WTYANDEXMAPITEMS_MAP_CENTER="Центр карты (координаты через запятую)" +MOD_WTYANDEXMAPITEMS_MAP_CENTER_DESC="Укажите координаты центра карты через запятую, например, 51.533562, 46.034266" +MOD_WTYANDEXMAPITEMS_MAP_ZOOM="Масштаб" +MOD_WTYANDEXMAPITEMS_MAP_TYPE="Тип карты" +MOD_WTYANDEXMAPITEMS_MAP_TYPE_MAP="Схема" +MOD_WTYANDEXMAPITEMS_MAP_TYPE_SATELLITE="Спутник" +MOD_WTYANDEXMAPITEMS_MAP_TYPE_HYBRID="Гибрид" +MOD_WTYANDEXMAPITEMS_MAP_WIDTH="Ширина карты" +MOD_WTYANDEXMAPITEMS_MAP_WIDTH_DESC="Указывать с единицами измерения, как в CSS - 500px или 100%" +MOD_WTYANDEXMAPITEMS_MAP_HEIGHT="Высота карты" +MOD_WTYANDEXMAPITEMS_MAP_HEIGHT_DESC="Указывать с единицами измерения, как в CSS - 500px или 100%" \ No newline at end of file diff --git a/language/ru-RU/mod_wtyandexmapitems.sys.ini b/language/ru-RU/mod_wtyandexmapitems.sys.ini new file mode 100644 index 0000000..c8fb42c --- /dev/null +++ b/language/ru-RU/mod_wtyandexmapitems.sys.ini @@ -0,0 +1,7 @@ +MOD_WTYANDEXMAPITEMS="WT Yandex map items" +MOD_WTYANDEXMAPITEMS_DESC="Выводит метки из различных компонентов на Яндекс.Карты" +MOD_WTYANDEXMAPITEMS_AFTER_INSTALL = "Спасибо за установку расширения" +MOD_WTYANDEXMAPITEMS_AFTER_DISCOVER_INSTALL = "Спасибо за установку расширения" +MOD_WTYANDEXMAPITEMS_AFTER_UPDATE = "Спасибо за обновление расширения" +MOD_WTYANDEXMAPITEMS_MAYBE_INTERESTING = "

Может быть интересно

" +MOD_WTYANDEXMAPITEMS_WHATS_NEW = "

v.1.0.0 Что нового?

Первая версия расширения.

Выводятся материалы Joomla в качестве меток Яндекс.карт. Категории материалов и контакты пока что не отображаются.

" \ No newline at end of file diff --git a/mod_wtyandexmapitems.xml b/mod_wtyandexmapitems.xml new file mode 100644 index 0000000..9ec4b99 --- /dev/null +++ b/mod_wtyandexmapitems.xml @@ -0,0 +1,356 @@ + + + MOD_WTYANDEXMAPITEMS + Sergey Tolkachyov + 13/09/2022 + (C) 2022 Sergey Tolkachyov. + GNU General Public License version 2 or later + info@web-tolk.ru + https://web-tolk.ru + 1.0.0 + MOD_WTYANDEXMAPITEMS_DESC + Joomla\Module\Wtyandexmapitems + script.php + + src + language + services + tmpl + + + language/en-GB/mod_wtyandexmapitems.ini + language/en-GB/mod_wtyandexmapitems.sys.ini + language/ru-RU/mod_wtyandexmapitems.ini + language/ru-RU/mod_wtyandexmapitems.sys.ini + + + +
+ + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + +
+
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + +
+
+
+ + https://web-tolk.ru/component/swjprojects/jupdate.html?element=mod_wtyandexmapitems + +
diff --git a/script.php b/script.php new file mode 100644 index 0000000..ce0251c --- /dev/null +++ b/script.php @@ -0,0 +1,264 @@ +script.php + * + * @package Joomla.Administrator + * @subpackage com_helloworld + * + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ +class mod_wtyandexmapitemsInstallerScript +{ + /** + * This method is called after a component is installed. + * + * @param \stdClass $parent - Parent object calling this method. + * + * @return void + */ + public function install($parent) + { + + } + + /** + * This method is called after a component is uninstalled. + * + * @param \stdClass $parent - Parent object calling this method. + * + * @return void + */ + public function uninstall($parent) + { + + + } + + /** + * This method is called after a component is updated. + * + * @param \stdClass $parent - Parent object calling object. + * + * @return void + */ + public function update($parent) + { + + } + + /** + * Runs just before any installation action is performed on the component. + * Verifications and pre-requisites should run in this function. + * + * @param string $type - Type of PreFlight action. Possible values are: + * - * install + * - * update + * - * discover_install + * @param \stdClass $parent - Parent object calling object. + * + * @return void + */ + public function preflight($type, $parent) + { + + } + /** + * @param $parent + * + * @return bool + * @throws Exception + * + * + * @since 1.0.0 + */ + protected function installDependencies($parent,$url) + { + // Load installer plugins for assistance if required: + PluginHelper::importPlugin('installer'); + + $app = Factory::getApplication(); + + $package = null; + + // This event allows an input pre-treatment, a custom pre-packing or custom installation. + // (e.g. from a JSON description). + $results = $app->triggerEvent('onInstallerBeforeInstallation', array($this, &$package)); + + if (in_array(true, $results, true)) + { + return true; + } + + if (in_array(false, $results, true)) + { + return false; + } + + + + // Download the package at the URL given. + $p_file = InstallerHelper::downloadPackage($url); + + // Was the package downloaded? + if (!$p_file) + { + $app->enqueueMessage(Text::_('COM_INSTALLER_MSG_INSTALL_INVALID_URL'), 'error'); + + return false; + } + + $config = Factory::getConfig(); + $tmp_dest = $config->get('tmp_path'); + + // Unpack the downloaded package file. + $package = InstallerHelper::unpack($tmp_dest . '/' . $p_file, true); + + // This event allows a custom installation of the package or a customization of the package: + $results = $app->triggerEvent('onInstallerBeforeInstaller', array($this, &$package)); + + if (in_array(true, $results, true)) + { + return true; + } + + if (in_array(false, $results, true)) + { + InstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); + + return false; + } + + // Get an installer instance. + $installer = new Installer(); + + /* + * Check for a Joomla core package. + * To do this we need to set the source path to find the manifest (the same first step as JInstaller::install()) + * + * This must be done before the unpacked check because JInstallerHelper::detectType() returns a boolean false since the manifest + * can't be found in the expected location. + */ + if (is_array($package) && isset($package['dir']) && is_dir($package['dir'])) + { + $installer->setPath('source', $package['dir']); + + if (!$installer->findManifest()) + { + InstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); + $app->enqueueMessage(Text::sprintf('COM_INSTALLER_INSTALL_ERROR', '.'), 'warning'); + + return false; + } + } + + // Was the package unpacked? + if (!$package || !$package['type']) + { + InstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); + $app->enqueueMessage(Text::_('COM_INSTALLER_UNABLE_TO_FIND_INSTALL_PACKAGE'), 'error'); + + return false; + } + + // Install the package. + if (!$installer->install($package['dir'])) + { + // There was an error installing the package. + $msg = Text::sprintf('COM_INSTALLER_INSTALL_ERROR', + Text::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type']))); + $result = false; + $msgType = 'error'; + } + else + { + // Package installed successfully. + $msg = Text::sprintf('COM_INSTALLER_INSTALL_SUCCESS', + Text::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type']))); + $result = true; + $msgType = 'message'; + } + + // This event allows a custom a post-flight: + $app->triggerEvent('onInstallerAfterInstaller', array($parent, &$package, $installer, &$result, &$msg)); + + $app->enqueueMessage($msg, $msgType); + + // Cleanup the install files. + if (!is_file($package['packagefile'])) + { + $package['packagefile'] = $config->get('tmp_path') . '/' . $package['packagefile']; + } + + InstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); + + return $result; + } + + + /** + * Runs right after any installation action is performed on the component. + * + * @param string $type - Type of PostFlight action. Possible values are: + * - * install + * - * update + * - * discover_install + * @param \stdClass $installer - Parent object calling object. + * + * @return void + */ + function postflight($type, $installer) + { + $smile = ''; + if($type != 'uninstall') + { + $smiles = ['☺', '😀', '😉', '😍', '😎', '😊', '🙏']; + $smile_key = array_rand($smiles, 1); + $smile = $smiles[$smile_key]; + } + + $element = strtoupper($installer->getElement()); + + echo " +
+
+

".$smile." ".Text::_($element."_AFTER_".$type)."
".Text::_($element)."

+ ".Text::_($element."_DESC"); + + echo Text::_($element."_WHATS_NEW"); + + echo "
+
+ +

Joomla Extensions

+

+ https://web-tolk.ru + info@web-tolk.ru +

+

Joomla Russian Community in Telegram

+ ".Text::_($element."_MAYBE_INTERESTING")." +
+ + "; + + } +} \ No newline at end of file diff --git a/services/provider.php b/services/provider.php new file mode 100644 index 0000000..229f3ee --- /dev/null +++ b/services/provider.php @@ -0,0 +1,41 @@ +registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Wtyandexmapitems')); + $container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\Wtyandexmapitems\\Site\\Helper')); + + $container->registerServiceProvider(new Module); + } +}; diff --git a/src/Dispatcher/Dispatcher.php b/src/Dispatcher/Dispatcher.php new file mode 100644 index 0000000..526af97 --- /dev/null +++ b/src/Dispatcher/Dispatcher.php @@ -0,0 +1,60 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace Joomla\Module\Wtyandexmapitems\Site\Dispatcher; + +\defined('JPATH_PLATFORM') or die; + +use Joomla\CMS\Application\CMSApplicationInterface; +use Joomla\CMS\Dispatcher\AbstractModuleDispatcher; +use Joomla\CMS\Extension\ModuleInterface; +use Joomla\Input\Input; +use Joomla\Module\Wtyandexmapitems\Site\Helper\WtyandexmapitemsHelper; +use Joomla\Registry\Registry; + +/** + * Dispatcher class for mod_wtyandexmapitems + * + * @since 4.0.0 + */ +class Dispatcher extends AbstractModuleDispatcher +{ + + /** + * The module extension. Used to fetch the module helper. + * + * @var ModuleInterface|null + * @since 3.0.9 + */ + private $moduleExtension; + + + public function __construct(\stdClass $module, CMSApplicationInterface $app, Input $input) + { + parent::__construct($module, $app, $input); + + $this->moduleExtension = $this->app->bootModule('mod_wtyandexmapitems', 'site'); + } + + /** + * Returns the layout data. + * + * @return array + * + * @since 4.0.0 + */ + protected function getLayoutData() + { + $data = parent::getLayoutData(); + + $data['placemarks'] = (new WtyandexmapitemsHelper)->getPlacemarks($data['params'], $this->getApplication()); + + return $data; + } +} diff --git a/src/Helper/WtyandexmapitemsHelper.php b/src/Helper/WtyandexmapitemsHelper.php new file mode 100644 index 0000000..b098b1e --- /dev/null +++ b/src/Helper/WtyandexmapitemsHelper.php @@ -0,0 +1,368 @@ +get('data_source', 'com_content.article'); + + + $placemarks = [ + 'type' => 'FeatureCollection', + 'features' => [] + ]; + + if ($context == 'com_content.article') + { + $placemarks["features"] = $this->getPlacemarksFromContentArticles($params, $app); + + } + + return $placemarks; + } + + public function getAjax():string + { + $app = Factory::getApplication(); + if ($app->getInput()->get('module_id')) + { + + $module = ModuleHelper::getModuleById($app->getInput()->get('module_id')); + + if ($module->module != 'mod_wtyandexmapitems') + { + + return json_encode(['error' => 'Module with specified module_id is not a mod_wtyandexmapitems type']); + + } + + } + else + { + $module = ModuleHelper::getModule('wtyandexmapitems'); + } + + $module_params = new Registry($module->params); + + return json_encode($this->getPlacemarks($module_params, $app)); + } + + public function getContentArticles($params, $app) + { + + /** @var \Joomla\Component\Content\Site\Model\ArticlesModel $model */ + $model = $app->bootComponent('com_content') + ->getMVCFactory()->createModel('Articles', 'Site', ['ignore_request' => true]); + + // Set application parameters in model + $appParams = $app->getParams(); + $model->setState('params', $appParams); + + $model->setState('list.start', 0); + $model->setState('filter.published', 1); + + // Set the filters based on the module params + $model->setState('list.limit', (int) $params->get('count', 5)); + + // This module does not use tags data + $model->setState('load_tags', false); + + // Access filter + $access = !ComponentHelper::getParams('com_content')->get('show_noauth'); + $authorised = Access::getAuthorisedViewLevels(Factory::getApplication()->getIdentity()->get('id')); + $model->setState('filter.access', $access); + + // Category filter + $model->setState('filter.category_id', $params->get('article_catid', array())); + + // Filter by language + $model->setState('filter.language', $app->getLanguageFilter()); + + // Filter by tag + $model->setState('filter.tag', $params->get('article_tag', array())); + + $model->setState('filter.featured', 'show'); + + // Check if we should trigger additional plugin events + $triggerEvents = $params->get('article_triggerevents', 1); + + // Retrieve Content + $items = $model->getItems(); + + /** + * Подключаем файл с языковыми константами для вывода "дней" в падежах + */ + $lang = Factory::getApplication()->getLanguage(); + $extension = 'com_content'; + $base_dir = JPATH_SITE; + $reload = true; + $lang->load($extension, $base_dir, $lang->getTag(), $reload); + + foreach ($items as &$item) + { + $item->readmore = \strlen(trim($item->fulltext)); + $item->slug = $item->id . ':' . $item->alias; + + if ($access || \in_array($item->access, $authorised)) + { + // We know that user has the privilege to view the article + $item->link = Route::_(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language)); + $item->linkText = Text::_('COM_CONTENT_READ_MORE'); + } + else + { + $item->link = new Uri(Route::_('index.php?option=com_users&view=login', false)); + $item->link->setVar('return', base64_encode(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language))); + $item->linkText = Text::_('COM_CONTENT_REGISTER_TO_READ_MORE'); + } + $item->introtext = HTMLHelper::_('content.prepare', $item->introtext, '', 'mod_wtyandexmapitems.content'); + + // Remove any images belongs to the text + if (!$params->get('image')) + { + $item->introtext = preg_replace('/]*>/', '', $item->introtext); + } + // Inserrt fields in $item + $item->jcfields = FieldsHelper::getFields('com_content.article', $item, true); + + // Show the Intro/Full image field of the article + if ($params->get('article_img_intro_full') !== 'none') + { + $images = json_decode($item->images); + $item->imageSrc = ''; + $item->imageAlt = ''; + $item->imageCaption = ''; + + if ($params->get('article_img_intro_full') === 'intro' && !empty($images->image_intro)) + { + $item->imageSrc = htmlspecialchars($images->image_intro, ENT_COMPAT, 'UTF-8'); + $item->imageAlt = htmlspecialchars($images->image_intro_alt, ENT_COMPAT, 'UTF-8'); + + if ($images->image_intro_caption) + { + $item->imageCaption = htmlspecialchars($images->image_intro_caption, ENT_COMPAT, 'UTF-8'); + } + } + elseif ($params->get('article_img_intro_full') === 'full' && !empty($images->image_fulltext)) + { + $item->imageSrc = htmlspecialchars($images->image_fulltext, ENT_COMPAT, 'UTF-8'); + $item->imageAlt = htmlspecialchars($images->image_fulltext_alt, ENT_COMPAT, 'UTF-8'); + + if ($images->image_intro_caption) + { + $item->imageCaption = htmlspecialchars($images->image_fulltext_caption, ENT_COMPAT, 'UTF-8'); + } + } + elseif ($params->get('article_img_intro_full') === 'image_from_field' && + $params->get('com_content_article_article_baloon_image_from_field_field_id')) + { + + foreach ($item->jcfields as $field) + { + if ($field->id == $params->get('com_content_article_article_baloon_image_from_field_field_id')) + { + if ($field->type == 'subform' && is_countable($field->subform_rows) && count($field->subform_rows) > 0) + { + + // Проходим ряды сабформы, потом каждое поле сабформы. Берём первое поле типа media + foreach ($field->subform_rows as $row){ + foreach ($row as $row_field){ + if($row_field->type == 'media' && empty($item->imageSrc)){ + // $image = json_decode($row_field->rawvalue); + // Почему то здесь приходит сразу декодированный массив + $row_field->rawvalue = (object)$row_field->rawvalue; + $item->imageSrc = htmlspecialchars($row_field->rawvalue->imagefile, ENT_COMPAT, 'UTF-8'); + $item->imageAlt = htmlspecialchars($row_field->rawvalue->alt_text, ENT_COMPAT, 'UTF-8'); + } + } + } + // 1-е изображение + } + else + { + // Одна картинка + $image = json_decode($field->rawvalue); + $item->imageSrc = htmlspecialchars($image->imagefile, ENT_COMPAT, 'UTF-8'); + $item->imageAlt = htmlspecialchars($image->alt_text, ENT_COMPAT, 'UTF-8'); + } + + } + } + } + } + + if ($triggerEvents) + { + $item->text = ''; + $app->triggerEvent('onContentPrepare', array('com_content.article', &$item, &$params, 0)); + + $results = $app->triggerEvent('onContentAfterTitle', array('com_content.article', &$item, &$params, 0)); + $item->afterDisplayTitle = trim(implode("\n", $results)); + + $results = $app->triggerEvent('onContentBeforeDisplay', array('com_content.article', &$item, &$params, 0)); + $item->beforeDisplayContent = trim(implode("\n", $results)); + + $results = $app->triggerEvent('onContentAfterDisplay', array('com_content.article', &$item, &$params, 0)); + $item->afterDisplayContent = trim(implode("\n", $results)); + } + else + { + $item->afterDisplayTitle = ''; + $item->beforeDisplayContent = ''; + $item->afterDisplayContent = ''; + } + + } + + return $items; + } + + /** + * Собираем из материалов массив с метками. + * @param $params + * @param $app + * + * @return array Массив меток + * + * @since 1.0.0 + */ + public function getPlacemarksFromContentArticles($params, $app){ + + $items = $this->getContentArticles($params, $app); + $placemarks = []; + $placemark_coords = []; + foreach ($items as $article) + { + + if (is_countable($article->jcfields)) + { + foreach ($article->jcfields as $field) + { + if ($field->id == $params->get('com_content_article_yandex_map_coords_field_id')) + { + $placemark_coords = explode(',', $field->rawvalue); + if ($field->type == 'wtyandexmap') + { + $fieldParams = $field->fieldparams; + $placemark_icon_code = $fieldParams->get('placemark_icon_code'); + $map_center = $fieldParams->get('map_center'); + } + } + } + } + else + { + // Полей нет вообще + continue; + } + // У нас есть пара координат + if (count($placemark_coords) == 2) + { + + $placemark = [ + 'type' => 'Feature', + 'id' => $article->id, + 'geometry' => [ + 'type' => 'Point', + 'coordinates' => $placemark_coords, + + ] + ]; + + // Показывать или нет заголовок матерала в метке + if ($params->get('show_article_title', '1') == 1) + { + $placemark['properties']['balloonContentHeader'] = $article->title; + $placemark['properties']['hintContent'] = $article->title; + } + + // Показывать или нет текст материала в метке и какой именно + + if ($params->get('article_baloon_text', 'fulltext') == 'fulltext') + { + $balloonContentBody = $article->fulltext; + } + elseif ($params->get('article_baloon_text', 'fulltext') == 'introtext') + { + $balloonContentBody = $article->introtext; + } + elseif ($params->get('article_baloon_text', 'fulltext') == 'text_from_field') + { + foreach ($article->jcfields as $field) + { + if ($params->get('com_content_article_article_baloon_text_from_field_field_id') && + $field->id == $params->get('com_content_article_article_baloon_text_from_field_field_id')) + { + + $balloonContentBody = [ + 'title' => $field->title, + 'text' => $field->value + ]; + } + } + } + else + { + $balloonContentBody = ''; + } + $layout = new FileLayout($params->get('balloonContentBody_layout','default_balloonContentBody'), JPATH_SITE . '/modules/mod_wtyandexmapitems/tmpl/sublayouts'); + + $displayData = [ + 'data' => $balloonContentBody, + 'module_params' => $params, + 'image' => [ + 'imageSrc' => $article->imageSrc, + 'imageAlt' => $article->imageAlt, + ], + 'link' => $article->link, + 'link_text' => $article->linkText + ]; + $placemark['properties']['balloonContentBody'] = $layout->render($displayData); + //$placemark['properties']['balloonContentFooter'] = ""; + + if ($placemark_icon_code) + { + $placemark["options"]["preset"] = $placemark_icon_code; + } + } + else + { + continue; + } + $placemarks[] = $placemark; + + } // foreach ($items as $article) + return $placemarks; + } +} diff --git a/tmpl/default.php b/tmpl/default.php new file mode 100644 index 0000000..9bec15f --- /dev/null +++ b/tmpl/default.php @@ -0,0 +1,97 @@ +get('yandex_map_api_key'))) +{ + $yandex_map_api_key = ''; +} +else +{ + $yandex_map_api_key = 'apikey=' . $params->get('yandex_map_api_key') . '&'; +} +$doc = Factory::getApplication()->getDocument(); +$wa = $doc->getWebAssetManager(); +$yandex_map_entry_point = ($params->get('yandex_api_type') == 'free' ? $yandex_map_api_entry_point_free : $yandex_map_api_entry_point_paid); +$yandex_map_script_uri = $yandex_map_entry_point . '/?' . $yandex_map_api_key . 'lang=' . Factory::getApplication()->getLanguage()->getTag(); +if(!$wa->assetExists('script','module.wtyandexmapitems.yandex') && !$wa->assetExists('script','plg.fields.wtyandexmap.yandex')){ + $wa->registerAndUseScript('module.wtyandexmapitems.yandex', $yandex_map_script_uri, [], [], ['core']); +} + +/** + * Координаты центра карты из параметров плагина + * и координаты из поля + */ +$map_center_coords = explode(',', $params->get('map_center')); + +$map_options = array( + 'zoom' => $params->get('map_zoom', 7), + 'type' => 'yandex#' . $params->get('map_type', 'map'), + 'center' => explode(',',$params->get('map_center','51.533562, 46.034266')) +); + + +$doc->addScriptOptions('mod_wtyandexmapitems' . $module->id, $map_options); + +$js_yandex_map_init = ' + ymaps.ready(init' . $module->id . '); + function init' . $module->id . '(){ + let mod_wtyandexmapitems' . $module->id. '_options = Joomla.getOptions("mod_wtyandexmapitems' . $module->id. '"); + console.log(mod_wtyandexmapitems' . $module->id. '_options); + var myMap' . $module->id . ' = new ymaps.Map("mod_wtyandexmapitems' . $module->id . '", mod_wtyandexmapitems' . $module->id. '_options ), + objectManager = new ymaps.ObjectManager({ + // Чтобы метки начали кластеризоваться, выставляем опцию. + clusterize: true, + // ObjectManager принимает те же опции, что и кластеризатор. + gridSize: 32, + clusterDisableClickZoom: true + }); + Joomla.request({ + url: window.location.origin + "/index.php?option=com_ajax&module=wtyandexmapitems&format=raw", + onSuccess: function (response, xhr){ + if (response !== ""){ + let placemarks = JSON.parse(response); + console.log(placemarks); + objectManager.add(placemarks); + myMap' . $module->id . '.geoObjects.add(objectManager); + + } + } + }); + + } + '; + +$wa->addInlineScript($js_yandex_map_init, [], ['defer' => true]); +?> + +
\ No newline at end of file diff --git a/tmpl/sublayouts/default_balloonContentBody.php b/tmpl/sublayouts/default_balloonContentBody.php new file mode 100644 index 0000000..04b7f8d --- /dev/null +++ b/tmpl/sublayouts/default_balloonContentBody.php @@ -0,0 +1,51 @@ + 'img-fluid', + 'loading' => 'lazy' + ]; + echo HTMLHelper::image($displayData['image']['imageSrc'], $displayData['image']['imageAlt'],$img_attribs); +} + + +if(is_array($data)): ?> +

+ + + +get('show_article_readmore','1') == 1 && !empty($displayData['link']) && !empty($displayData['link_text'])): + $link_attribs = [ + 'class' => 'btn btn-sm btn-primary' + ]; + echo HTMLHelper::link(OutputFilter::ampReplace(htmlspecialchars($displayData['link'], ENT_COMPAT, 'UTF-8', false)),$displayData['link_text'], $link_attribs); +endif; diff --git a/tmpl/sublayouts/default_balloonContentBodyCustom.php b/tmpl/sublayouts/default_balloonContentBodyCustom.php new file mode 100644 index 0000000..04b7f8d --- /dev/null +++ b/tmpl/sublayouts/default_balloonContentBodyCustom.php @@ -0,0 +1,51 @@ + 'img-fluid', + 'loading' => 'lazy' + ]; + echo HTMLHelper::image($displayData['image']['imageSrc'], $displayData['image']['imageAlt'],$img_attribs); +} + + +if(is_array($data)): ?> +

+ + + +get('show_article_readmore','1') == 1 && !empty($displayData['link']) && !empty($displayData['link_text'])): + $link_attribs = [ + 'class' => 'btn btn-sm btn-primary' + ]; + echo HTMLHelper::link(OutputFilter::ampReplace(htmlspecialchars($displayData['link'], ENT_COMPAT, 'UTF-8', false)),$displayData['link_text'], $link_attribs); +endif;