install.yaml XLite\Model\Config: - name: enabled category: \ type: checkbox orderby: 100 value: N widgetParameters: { trusted: 1 } translations: - code: en option_name: Enable option_comment: Enable/Disable the multilanguage banner slider - code: fr option_name: Active option_comment: (Dés)activer le curseur de la bannière multilingue - code: ie option_name: Gníomhach option_comment: Cumasaigh/Díchumasaigh an sleamhnán meirge ilteangach - name: interval category: \ type: text orderby: 200 value: '5' widgetParameters: { trusted: 1 } translations: - code: en option_name: Banner interval (in seconds) option_comment: Set to "0" to disable automatic rotation - code: fr option_name: Intervalle de bannière (en secondes) option_comment: Réglez sur «0» pour désactiver la rotation automatique - code: ie option_name: Eatramh meirge (i soicindí) option_comment: Socraigh go "0" chun rothlú uathoibríoch a dhíchumasú ------------------------ main.yaml version: 5.4.1.0 type: common authorName: 'Lord Brownrigg Solutions' moduleName: 'Multilanguage Banner Rotation' description: 'Adds a banner rotation engine capable of selecting multilanguage images.' minorRequiredCoreVersion: 1 dependsOn: { } incompatibleWith: { } skins: { } showSettingsForm: true canDisable: true ------------------------ Controller/Admin/MlBanner.php \\Controller\Admin; /** * Multilanguage banner controller */ class MlBanner extends \XLite\Controller\Admin\Settings { /** * Recommended module URL (run-time cache) * * @var string */ protected $recommendedModuleURL = null; /** * Check ACL permissions * * @return boolean */ public function checkACL() { return parent::checkACL() || \XLite\Core\Auth::getInstance()->isPermissionAllowed('manage banners'); } /** * Return the current page title (for the content area) * * @return string */ public function getTitle() { return static::t('Front page'); } /** * Update model * * @return void */ public function doActionUpdate() { $list = new \XLite\Module\\\View\ItemsList\MlBannerImages(); $list->processQuick(); $this->getModelForm()->performAction('update'); } /** * getModelFormClass * * @return string * */ protected function getModelFormClass() { return 'XLite\View\Model\Settings'; } /** * Get options for current tab (category) * * @return \Xlite\Model\Config[] */ public function getOptions() { return \XLite\Core\Database::getRepo('XLite\Model\Config')->findByCategoryAndVisible('\'); } } ------------------------ Model/Image/MlBannerImage.php \\Model\Image; /** * @Entity * @Table (name="ml_banner_image") */ class MlBannerImage extends \XLite\Model\Base\Image { /** * Relation to a MlBannerTranslation entity * * @var \XLite\Module\\\Model\MlBannerTranslation * * @OneToOne (targetEntity="XLite\Module\\\Model\MlBannerTranslation", inversedBy="image") * @JoinColumn (name="ml_banner_translation_id", referencedColumnName="label_id", onDelete="CASCADE") */ protected $mlBannerTranslation; /** * alt * * @Column (type="string", length=255) */ protected $alt; /** * Get alt * * @return string */ public function getAlt() { return $this->alt; } /** * Set alt * * @param string $alt * @return mlBannerImage */ public function setAlt($alt) { $this->alt = $alt; return $this; } } ------------------------ Model/MlBanner.php \\Model; /** * @Entity * @Table (name="ml_banner") */ class MlBanner extends \XLite\Model\Base\I18n { /** * @Id * @GeneratedValue (strategy="AUTO") * @Column (type="integer") */ protected $id; /** * @Column (type="boolean") */ protected $enabled = true; /** * Position * * @var integer * * @Column (type="integer") */ protected $position = 0; public function __construct(array $data = array()) { parent::__construct($data); } public function getID() { return $this->id; } public function getEnabled() { return $this->enabled; } public function setEnabled($value) { $this->enabled = $value; return $this; } public function getPosition() { return $this->position; } public function setPosition($position) { $this->position = $position; return $this; } } ------------------------ Model/MlBannerTranslation.php \\Model; /** * @Entity * * @Table (name="ml_banner_translations") */ class MlBannerTranslation extends \XLite\Model\Base\Translation { /** * Image * * @var \XLite\Module\\\Model\Image\MlBannerImage * @OneToOne (targetEntity="XLite\Module\\\Model\Image\MlBannerImage", mappedBy="mlBannerTranslation", cascade={"all"}) */ protected $image; /** * @Column (type="text") */ protected $link; /** * Get image * * @return \XLite\Module\\\Model\Image\MlBannerImage */ public function getImage() { return $this->image; } /** * Set image * * @param \XLite\Module\\\Model\Image\MlBannerImage $image * @return MlBannerTranslation */ public function setImage($image) { $this->image = $image; return $this; } /** * Get link * * @return string */ public function getLink() { return $this->link; } /** * Set link * * @param string $link * @return MlBannerTranslation */ public function setLink($link) { $this->link = $link; return $this; } } ------------------------ Model/Repo/Image/MlBannerImage.php \\Model\Repo\Image; /** * * @Api\Operation\Create(modelClass="XLite\Module\\\Model\Image\MlBannerImage", summary="Add new multilanguage banner image") * @Api\Operation\Read(modelClass="XLite\Module\\\Model\Image\MlBannerImage", summary="Retrieve multilanguage banner image by id") * @Api\Operation\ReadAll(modelClass="XLite\Module\\\Model\Image\MlBannerImage", summary="Retrieve all multilanguage banner images") * @Api\Operation\Update(modelClass="XLite\Module\\\Model\Image\MlBannerImage", summary="Update multilanguage banner image by id") * @Api\Operation\Delete(modelClass="XLite\Module\\\Model\Image\MlBannerImage", summary="Delete multilanguage banner image by id") */ class MlBannerImage extends \XLite\Model\Repo\Base\Image { /** * Returns the name of the directory within 'root/images' where images stored * * @return string */ public function getStorageName() { return 'ml_banner'; } } ------------------------ Model/Repo/MlBanner.php \\Model\Repo; class MlBanner extends \XLite\Model\Repo\ARepo { protected $defaultOrderBy = 'id'; } ------------------------ View/Form/MlBanner.php \\View\Form; class MlBanner extends \XLite\View\Form\AForm { /** * getDefaultTarget * * @return string */ protected function getDefaultTarget() { return 'ml_banner'; } /** * getDefaultAction * * @return string */ protected function getDefaultAction() { return 'update'; } } ------------------------ View/ItemsList/MlBannerImages.php \\View\ItemsList; use XLite\View\FormField\FileUploader\AFileUploader; class MlBannerImages extends \XLite\View\ItemsList\Model\Table { /** * Get a list of CSS files required to display the widget properly * * @return array */ public function getCSSFiles() { $list = parent::getCSSFiles(); $list[] = 'modules///images/style.css'; return $list; } /** * Define columns structure * * @return array */ protected function defineColumns() { return array( 'image' => array( static::COLUMN_NAME => static::t('Image'), static::COLUMN_LINK => 'image', static::COLUMN_CLASS => 'XLite\View\FormField\Inline\FileUploader\Image', static::COLUMN_PARAMS => array( AFileUploader::PARAM_REQUIRED => true, AFileUploader::PARAM_IS_REMOVABLE => false, ), static::COLUMN_ORDERBY => 100, ), 'link' => array( static::COLUMN_NAME => static::t('Link'), static::COLUMN_LINK => 'link', static::COLUMN_CLASS => 'XLite\View\FormField\Inline\Input\Text', static::COLUMN_MAIN => true, static::COLUMN_ORDERBY => 200, ), ); } /** * Define repository name * * @return string */ protected function defineRepositoryName() { return 'XLite\Module\\\Model\MlBanner'; } /** * Return entities list * * @param \XLite\Core\CommonCell $cnd Search condition * @param boolean $countOnly Return items list or only its size OPTIONAL * * @return array|integer */ protected function getData(\XLite\Core\CommonCell $cnd, $countOnly = false) { $repo = \XLite\Core\Database::getRepo('XLite\Module\\\Model\MlBanner'); return $countOnly ? $repo->count() : $repo->findBy([], ['position' => 'ASC']); } /** * Get create button label * * @return string */ protected function getCreateButtonLabel() { return 'Add banner'; } /** * Creation button position * * @return integer */ protected function isCreation() { return static::CREATE_INLINE_TOP; } /** * Inline creation mechanism position * * @return integer */ protected function isInlineCreation() { return static::CREATE_INLINE_TOP; } /** * Mark list as switchable (enable / disable) * * @return boolean */ protected function isSwitchable() { return true; } /** * Mark list as removable * * @return boolean */ protected function isRemoved() { return true; } /** * Mark list as sortable * * @return integer */ protected function getSortableType() { return static::SORT_TYPE_MOVE; } /** * Get container class * * @return string */ protected function getContainerClass() { return parent::getContainerClass() . ' banner-rotation-images'; } /** * @inheritdoc */ protected function getPanelClass() { return ''; } protected function wrapWithFormByDefault() { return true; } } ------------------------ View/ItemsList/Model/MlBanner.php \\View\ItemsList\Model; use XLite\View\FormField\FileUploader\AFileUploader; class MlBanner extends \XLite\View\ItemsList\Model\Table { protected function defineColumns() { return array( 'image' => array( static::COLUMN_CLASS => 'XLite\View\FormField\Inline\FileUploader\Image', static::COLUMN_NAME => static::t('Image'), static::COLUMN_LINK => 'image', static::COLUMN_PARAMS => array( AFileUploader::PARAM_REQUIRED => true, AFileUploader::PARAM_IS_REMOVABLE => false, ), static::COLUMN_ORDERBY => 100, ), 'link' => array( static::COLUMN_CLASS => 'XLite\View\FormField\Inline\Input\Text', static::COLUMN_NAME => static::t('Link'), static::COLUMN_LINK => 'link', static::COLUMN_MAIN => true, static::COLUMN_ORDERBY => 200, ), ); } protected function defineRepositoryName() { return 'XLite\Module\\\Model\MlBanner'; } protected function getData(\XLite\Core\CommonCell $cnd, $countOnly = false) { $repo = \XLite\Core\Database::getRepo($this->defineRepositoryName()); return $countOnly ? $repo->count() : $repo->findBy([], ['position' => 'ASC']); } protected function getCreateButtonLabel() { return 'Add bannder'; } protected function isCreation() { return static::CREATE_INLINE_TOP; } protected function isInlineCreation() { return static::CREATE_INLINE_TOP; } protected function isSwitchable() { return true; } protected function isRemoved() { return true; } protected function getSortableType() { return static::SORT_TYPE_MOVE; } protected function getContainerClass() { return parent::getContainerClass() . ' banner-rotation-images'; } protected function getPanelClass() { return ''; } protected function wrapWithFormByDefault() { return true; } protected function getFormTarget() { return 'ml_banner'; } } ------------------------ View/MlBanner.php \\View; /** * MlBanner widget * * @ListChild (list="center", zone="customer", weight="100") */ class MlBanner extends \XLite\View\AView { /** * Return list of allowed targets * @return array */ public static function getAllowedTargets() { $list = parent::getAllowedTargets(); $list[] = 'main'; return $list; } /** * Get a list of CSS files required to display the widget properly * * @return array */ public function getCSSFiles() { $list = parent::getCSSFiles(); $list[] = 'modules///style.css'; return $list; } /** * Get JS files * * @return array */ public function getJSFiles() { return array_merge( parent::getJSFiles(), array( 'modules///jssor_init.js', 'modules///jssor.slider-28.0.0.min.js' ) ); } /** * Return widget default template * * @return string */ protected function getDefaultTemplate() { return 'modules///body.twig'; } /** * Get slides * * @return array */ protected function getSlides() { $slides = \XLite\Core\Database::getRepo('XLite\Module\\\Model\MlBanner')->findBy( ['enabled' => true], ['position' => 'ASC'] ); return $slides; } /** * Get images * * @return array */ protected function getImages() { $slides = $this->getSlides(); $images = array_map( function ($slide) { return $slide->getImage(); }, $slides ); return array_filter($images); } /** * Get image count * * @return int */ protected function getImageCount() { $cacheParams = $this->getCacheParameters(); $cacheParams[] = 'getImageCount'; return $this->executeCached(function () { return count($this->getImages()); }, $cacheParams); } /** * Is multilanguage banner enabled * * @return boolean */ protected function isRotationEnabled() { return \XLite\Core\Config::getInstance()->->->enabled && 1 < $this->getImageCount(); } /** * Check if widget is visible * * @return boolean */ protected function isVisible() { return parent::isVisible() && !$this->isForceChangePassword() && \XLite\Core\Config::getInstance()->->->enabled && $this->getImageCount() > 0; } /** * Get commented data * * @return array */ protected function getCommentedData() { return [ 'pause' => false, 'interval' => round(\XLite\Core\Config::getInstance()->->->interval * 1000), ]; } /** * Cache availability * * @return boolean */ protected function isCacheAvailable() { return true; } } ------------------------ View/Model/MlBanner.php \\View\Model; class MlBanner extends \XLite\View\Model\Settings { /** * Return name of web form widget class * * @return string */ protected function getFormClass() { return 'XLite\Module\\\View\Form\MlBanner'; } } ------------------------ View/Tabs/FrontPage.php \\View\Tabs; class FrontPage extends \XLite\View\Tabs\FrontPage implements \XLite\Base\IDecorator { /** * Returns the list of targets where this widget is available * * @return string[] */ public static function getAllowedTargets() { $list = parent::getAllowedTargets(); $list[] = 'ml_banner'; return $list; } /** * @return array */ protected function defineTabs() { $list = parent::defineTabs(); $list['ml_banner'] = [ 'weight' => 250, 'title' => static::t('Multilanguage Banner'), 'template' => 'modules///body.twig', ]; return $list; } } ------------------------