├── Api ├── Data │ ├── CategoryInterface.php │ ├── PostInterface.php │ └── TagInterface.php └── Repository │ ├── AuthorRepositoryInterface.php │ ├── CategoryRepositoryInterface.php │ ├── PostRepositoryInterface.php │ └── TagRepositoryInterface.php ├── Block ├── Adminhtml │ ├── Author.php │ ├── Author │ │ ├── Edit.php │ │ ├── Edit │ │ │ └── Form.php │ │ └── Grid.php │ ├── Category.php │ ├── Category │ │ ├── Edit.php │ │ ├── Edit │ │ │ ├── Form.php │ │ │ ├── Tab │ │ │ │ ├── General.php │ │ │ │ └── Meta.php │ │ │ └── Tabs.php │ │ ├── Grid.php │ │ └── Grid │ │ │ └── Renderer │ │ │ └── Title.php │ ├── Post.php │ └── Post │ │ ├── Edit.php │ │ └── Edit │ │ ├── Form.php │ │ ├── Sidebar.php │ │ ├── Sidebar │ │ ├── Author.php │ │ ├── Categories.php │ │ ├── Image.php │ │ ├── Publish.php │ │ ├── Stores.php │ │ └── Tags.php │ │ ├── Tab │ │ ├── General.php │ │ ├── Meta.php │ │ └── Products.php │ │ └── Tabs.php ├── Author │ └── View.php ├── Catalog │ └── RelatedPosts.php ├── Category │ ├── Rss.php │ └── View.php ├── Html │ └── Pager.php ├── Post │ ├── AbstractBlock.php │ ├── Meta.php │ ├── Pinned.php │ ├── PostList.php │ ├── PostList │ │ └── Toolbar.php │ ├── Recent.php │ ├── View.php │ └── View │ │ ├── RelatedPosts.php │ │ └── RelatedProducts.php ├── Search │ └── Result.php ├── Sidebar │ ├── CategoryTree.php │ ├── Recent.php │ ├── Search.php │ └── TagCloud.php └── Tag │ └── View.php ├── CHANGELOG.md ├── Controller ├── Adminhtml │ ├── Author.php │ ├── Author │ │ ├── Edit.php │ │ ├── Index.php │ │ └── Save.php │ ├── Category.php │ ├── Category │ │ ├── Delete.php │ │ ├── Edit.php │ │ ├── Index.php │ │ ├── NewAction.php │ │ └── Save.php │ ├── Post.php │ └── Post │ │ ├── Delete.php │ │ ├── Edit.php │ │ ├── FileUpload.php │ │ ├── Index.php │ │ ├── InlineEdit.php │ │ ├── MassDelete.php │ │ ├── MassStatus.php │ │ ├── NewAction.php │ │ ├── RelatedProductsGrid.php │ │ └── Save.php ├── Author │ └── View.php ├── Category.php ├── Category │ ├── Index.php │ ├── Rss.php │ └── View.php ├── Post.php ├── Post │ └── View.php ├── Router.php ├── Search │ └── Result.php └── Tag │ └── View.php ├── Helper ├── Category.php └── Form │ └── Post │ └── Storeview.php ├── LICENSE.txt ├── Model ├── Author.php ├── Category.php ├── Config.php ├── Config │ ├── FileProcessor.php │ └── Source │ │ └── CommentProvider.php ├── Post.php ├── Post │ ├── Attribute │ │ └── Source │ │ │ ├── Author.php │ │ │ └── Status.php │ └── PostList │ │ └── Toolbar.php ├── ResourceModel │ ├── Category.php │ ├── Category │ │ └── Collection.php │ ├── Post.php │ ├── Post │ │ ├── Collection.php │ │ └── Grid │ │ │ └── Collection.php │ ├── Tag.php │ └── Tag │ │ └── Collection.php ├── Tag.php ├── Url.php └── UrlInterface.php ├── Observer └── TopMenuObserver.php ├── README.md ├── Repository ├── AuthorRepository.php ├── CategoryRepository.php ├── PostRepository.php └── TagRepository.php ├── Setup ├── InstallData.php ├── InstallData │ ├── CategorySetup.php │ └── PostSetup.php ├── InstallSchema.php ├── UpgradeData.php ├── UpgradeSchema.php └── Upgrade_1_0_4.php ├── Ui ├── Component │ ├── DataProvider.php │ └── Listing │ │ └── Column │ │ └── PostActions.php └── Post │ ├── Form │ ├── Control │ │ ├── BackButton.php │ │ ├── DeleteButton.php │ │ ├── GenericButton.php │ │ ├── PreviewButton.php │ │ ├── SaveAndContinueButton.php │ │ └── SaveButton.php │ ├── DataProvider.php │ └── ProductDataProvider.php │ └── Source │ ├── Author.php │ ├── CategoryTree.php │ ├── Status.php │ └── Tags.php ├── composer.json ├── docs ├── SUMMARY.md ├── WELCOME.md ├── guide │ ├── categories.md │ ├── posts.md │ ├── quick_start.md │ └── settings.md ├── images │ ├── category-structure.png │ └── posts-create-new.png └── setup │ ├── disabling.md │ ├── installation.md │ └── upgrade.md ├── etc ├── acl.xml ├── adminhtml │ ├── menu.xml │ ├── routes.xml │ └── system.xml ├── config.xml ├── di.xml ├── frontend │ ├── di.xml │ ├── events.xml │ └── routes.xml ├── module.xml ├── webapi.xml └── widget.xml ├── i18n ├── he_IL.csv └── nl_NL.csv ├── registration.php └── view ├── adminhtml ├── layout │ ├── blog_author_edit.xml │ ├── blog_category_edit.xml │ ├── blog_post_edit.xml │ ├── blog_post_index.xml │ └── blog_post_relatedproductsgrid.xml ├── requirejs-config.js ├── templates │ └── post │ │ └── edit │ │ ├── form.phtml │ │ ├── sidebar.phtml │ │ └── sidebar │ │ └── tags.phtml ├── ui_component │ ├── blog_post_form.xml │ ├── blog_post_form_product_listing.xml │ └── blog_post_listing.xml └── web │ ├── css │ └── source │ │ ├── _module.less │ │ └── module │ │ ├── category │ │ └── _edit.less │ │ └── post │ │ ├── _form.less │ │ └── _list.less │ ├── js │ ├── lib │ │ └── tokenize2.js │ └── post │ │ └── form │ │ ├── area.js │ │ ├── id.js │ │ ├── input-limiter.js │ │ └── tags.js │ └── template │ ├── grid │ └── cells │ │ └── actions.html │ └── post │ └── form │ ├── area.html │ └── tags.html └── frontend ├── layout ├── blog_author_view.xml ├── blog_category_index.xml ├── blog_category_view.xml ├── blog_default.xml ├── blog_post_view.xml ├── blog_search_result.xml ├── blog_tag_view.xml └── catalog_product_view.xml ├── templates ├── author │ └── view.phtml ├── catalog │ └── related_posts.phtml ├── category │ ├── rss.phtml │ └── view.phtml ├── html │ └── copyright.phtml ├── post │ ├── list.phtml │ ├── list │ │ ├── toolbar.phtml │ │ └── toolbar │ │ │ └── amount.phtml │ ├── meta │ │ ├── footer.phtml │ │ ├── header.phtml │ │ └── js.phtml │ ├── pinned.phtml │ ├── recent.phtml │ ├── view.phtml │ └── view │ │ ├── comments.phtml │ │ ├── related_posts.phtml │ │ └── related_products.phtml ├── search │ └── result.phtml ├── sidebar │ ├── category_tree.phtml │ ├── recent.phtml │ ├── rss.phtml │ ├── search.phtml │ └── tag_cloud.phtml └── tag │ └── view.phtml └── web └── css └── source ├── _module.less └── module ├── _copyright.less ├── _extends.less ├── _sidebar.less ├── _topmenu.less ├── catalog └── _related_posts.less └── post ├── _list.less ├── _pinned.less └── _view.less /Api/Data/TagInterface.php: -------------------------------------------------------------------------------- 1 | _controller = 'adminhtml_author'; 15 | $this->_blockGroup = 'Mirasvit_Blog'; 16 | 17 | parent::_construct(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Block/Adminhtml/Author/Edit.php: -------------------------------------------------------------------------------- 1 | _objectId = 'entity_id'; 17 | $this->_controller = 'adminhtml_author'; 18 | $this->_blockGroup = 'Mirasvit_Blog'; 19 | 20 | $this->buttonList->remove('save'); 21 | 22 | $this->getToolbar()->addChild( 23 | 'save-split-button', 24 | 'Magento\Backend\Block\Widget\Button\SplitButton', 25 | [ 26 | 'id' => 'save-split-button', 27 | 'label' => __('Save'), 28 | 'class_name' => 'Magento\Backend\Block\Widget\Button\SplitButton', 29 | 'button_class' => 'widget-button-update', 30 | 'options' => [ 31 | [ 32 | 'id' => 'save-button', 33 | 'label' => __('Save'), 34 | 'default' => true, 35 | 'data_attribute' => [ 36 | 'mage-init' => [ 37 | 'button' => [ 38 | 'event' => 'save', 39 | 'target' => '#edit_form', 40 | ], 41 | ], 42 | ], 43 | ], 44 | [ 45 | 'id' => 'save-continue-button', 46 | 'label' => __('Save & Continue Edit'), 47 | 'data_attribute' => [ 48 | 'mage-init' => [ 49 | 'button' => [ 50 | 'event' => 'saveAndContinueEdit', 51 | 'target' => '#edit_form', 52 | ], 53 | ], 54 | ], 55 | ], 56 | ], 57 | ] 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Block/Adminhtml/Author/Edit/Form.php: -------------------------------------------------------------------------------- 1 | formFactory = $formFactory; 35 | $this->registry = $registry; 36 | 37 | parent::__construct($context); 38 | } 39 | 40 | /** 41 | * @return $this 42 | * @throws LocalizedException 43 | */ 44 | protected function _prepareForm() 45 | { 46 | $form = $this->formFactory->create()->setData([ 47 | 'id' => 'edit_form', 48 | 'action' => $this->getUrl('*/*/save', ['id' => $this->getRequest()->getParam('id')]), 49 | 'method' => 'post', 50 | 'enctype' => 'multipart/form-data', 51 | ]); 52 | 53 | $form->setUseContainer(true); 54 | $this->setForm($form); 55 | 56 | $this->setForm($form); 57 | 58 | /** @var Author $author */ 59 | $author = $this->registry->registry('current_model'); 60 | 61 | $fieldset = $form->addFieldset('edit_fieldset', [ 62 | 'legend' => __('Author Information'), 63 | ]); 64 | 65 | if ($author->getId()) { 66 | $fieldset->addField('user_id', 'hidden', [ 67 | 'name' => 'user_id', 68 | 'value' => $author->getId(), 69 | ]); 70 | } 71 | 72 | $fieldset->addField('display_name', 'text', [ 73 | 'label' => __('Display Name'), 74 | 'name' => 'display_name', 75 | 'value' => $author->getDisplayName(), 76 | 'required' => true, 77 | ]); 78 | 79 | $fieldset->addField('bio', 'textarea', [ 80 | 'label' => __('Biographical Info'), 81 | 'name' => 'bio', 82 | 'value' => $author->getBio(), 83 | 'required' => false, 84 | ]); 85 | 86 | return parent::_prepareForm(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Block/Adminhtml/Author/Grid.php: -------------------------------------------------------------------------------- 1 | authorFactory = $authorFactory; 32 | 33 | parent::__construct($context, $backendHelper, $data); 34 | } 35 | 36 | /** 37 | * @param Author $row 38 | * 39 | * @return string 40 | */ 41 | public function getRowUrl($row) 42 | { 43 | return $this->getUrl('*/*/edit', ['id' => $row->getId()]); 44 | } 45 | 46 | /** 47 | * {@inheritdoc} 48 | */ 49 | protected function _construct() 50 | { 51 | parent::_construct(); 52 | 53 | $this->setId('blog_author_grid'); 54 | $this->setDefaultSort('user_id'); 55 | $this->setDefaultDir('DESC'); 56 | $this->setSaveParametersInSession(true); 57 | } 58 | 59 | /** 60 | * @return $this 61 | */ 62 | protected function _prepareCollection() 63 | { 64 | $collection = $this->authorFactory->create()->getCollection(); 65 | 66 | $this->setCollection($collection); 67 | 68 | return parent::_prepareCollection(); 69 | } 70 | 71 | /** 72 | * @return $this 73 | * @throws Exception 74 | */ 75 | protected function _prepareColumns() 76 | { 77 | $this->addColumn('username', [ 78 | 'header' => __('Username'), 79 | 'index' => 'username', 80 | ]); 81 | 82 | $this->addColumn('firstname', [ 83 | 'header' => __('First Name'), 84 | 'index' => 'firstname', 85 | ]); 86 | 87 | $this->addColumn('lastname', [ 88 | 'header' => __('Last Name'), 89 | 'index' => 'lastname', 90 | ]); 91 | 92 | return parent::_prepareColumns(); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Block/Adminhtml/Category.php: -------------------------------------------------------------------------------- 1 | _controller = 'adminhtml_category'; 15 | $this->_blockGroup = 'Mirasvit_Blog'; 16 | 17 | parent::_construct(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Block/Adminhtml/Category/Edit.php: -------------------------------------------------------------------------------- 1 | _objectId = 'entity_id'; 17 | $this->_controller = 'adminhtml_category'; 18 | $this->_blockGroup = 'Mirasvit_Blog'; 19 | 20 | $this->buttonList->remove('save'); 21 | 22 | $this->getToolbar()->addChild( 23 | 'save-split-button', 24 | 'Magento\Backend\Block\Widget\Button\SplitButton', 25 | [ 26 | 'id' => 'save-split-button', 27 | 'label' => __('Save'), 28 | 'class_name' => 'Magento\Backend\Block\Widget\Button\SplitButton', 29 | 'button_class' => 'widget-button-update', 30 | 'options' => [ 31 | [ 32 | 'id' => 'save-button', 33 | 'label' => __('Save'), 34 | 'default' => true, 35 | 'data_attribute' => [ 36 | 'mage-init' => [ 37 | 'button' => [ 38 | 'event' => 'save', 39 | 'target' => '#edit_form', 40 | ], 41 | ], 42 | ], 43 | ], 44 | [ 45 | 'id' => 'save-continue-button', 46 | 'label' => __('Save & Continue Edit'), 47 | 'data_attribute' => [ 48 | 'mage-init' => [ 49 | 'button' => [ 50 | 'event' => 'saveAndContinueEdit', 51 | 'target' => '#edit_form', 52 | ], 53 | ], 54 | ], 55 | ], 56 | ], 57 | ] 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Block/Adminhtml/Category/Edit/Form.php: -------------------------------------------------------------------------------- 1 | formFactory = $formFactory; 25 | 26 | parent::__construct($context); 27 | } 28 | 29 | /** 30 | * {@inheritdoc} 31 | */ 32 | protected function _prepareForm() 33 | { 34 | $form = $this->formFactory->create()->setData([ 35 | 'id' => 'edit_form', 36 | 'action' => $this->getUrl('*/*/save', ['id' => $this->getRequest()->getParam('id')]), 37 | 'method' => 'post', 38 | 'enctype' => 'multipart/form-data', 39 | ]); 40 | 41 | $form->setUseContainer(true); 42 | $this->setForm($form); 43 | 44 | return parent::_prepareForm(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Block/Adminhtml/Category/Edit/Tab/Meta.php: -------------------------------------------------------------------------------- 1 | formFactory = $formFactory; 35 | $this->registry = $registry; 36 | 37 | parent::__construct($context); 38 | } 39 | 40 | /** 41 | * @return $this 42 | * @throws LocalizedException 43 | */ 44 | protected function _prepareForm() 45 | { 46 | $form = $this->formFactory->create(); 47 | $this->setForm($form); 48 | 49 | /** @var Category $category */ 50 | $category = $this->registry->registry('current_model'); 51 | 52 | $fieldset = $form->addFieldset('edit_fieldset', [ 53 | 'legend' => __('Search Engine Optimization'), 54 | ]); 55 | 56 | $fieldset->addField('url_key', 'text', [ 57 | 'label' => __('URL Key'), 58 | 'name' => 'url_key', 59 | 'value' => $category->getUrlKey(), 60 | ]); 61 | 62 | $fieldset->addField('meta_title', 'text', [ 63 | 'label' => __('Meta Title'), 64 | 'name' => 'meta_title', 65 | 'value' => $category->getMetaTitle(), 66 | ]); 67 | 68 | $fieldset->addField('meta_description', 'textarea', [ 69 | 'label' => __('Meta Description'), 70 | 'name' => 'meta_description', 71 | 'value' => $category->getMetaDescription(), 72 | ]); 73 | 74 | $fieldset->addField('meta_keywords', 'textarea', [ 75 | 'label' => __('Meta Keywords'), 76 | 'name' => 'meta_keywords', 77 | 'value' => $category->getMetaKeywords(), 78 | ]); 79 | 80 | return parent::_prepareForm(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Block/Adminhtml/Category/Edit/Tabs.php: -------------------------------------------------------------------------------- 1 | setDestElementId('edit_form'); 14 | } 15 | 16 | /** 17 | * {@inheritdoc} 18 | */ 19 | protected function _beforeToHtml() 20 | { 21 | $this->addTab('general_section', [ 22 | 'label' => __('General Information'), 23 | 'content' => $this->getLayout() 24 | ->createBlock('\Mirasvit\Blog\Block\Adminhtml\Category\Edit\Tab\General')->toHtml(), 25 | ]); 26 | 27 | $this->addTab('meta_section', [ 28 | 'label' => __('Search Engine Optimization'), 29 | 'content' => $this->getLayout() 30 | ->createBlock('\Mirasvit\Blog\Block\Adminhtml\Category\Edit\Tab\Meta')->toHtml(), 31 | ]); 32 | 33 | return parent::_beforeToHtml(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Block/Adminhtml/Category/Grid/Renderer/Title.php: -------------------------------------------------------------------------------- 1 | getLevel() * 10) . $row->getName(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Block/Adminhtml/Post.php: -------------------------------------------------------------------------------- 1 | _controller = 'adminhtml_post'; 15 | $this->_blockGroup = 'Mirasvit_Blog'; 16 | 17 | parent::_construct(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Block/Adminhtml/Post/Edit.php: -------------------------------------------------------------------------------- 1 | _objectId = 'entity_id'; 17 | $this->_controller = 'adminhtml_post'; 18 | $this->_blockGroup = 'Mirasvit_Blog'; 19 | 20 | $this->buttonList->remove('save'); 21 | 22 | $this->getToolbar()->addChild( 23 | 'save-split-button', 24 | 'Magento\Backend\Block\Widget\Button\SplitButton', 25 | [ 26 | 'id' => 'save-split-button', 27 | 'label' => __('Save'), 28 | 'class_name' => 'Magento\Backend\Block\Widget\Button\SplitButton', 29 | 'button_class' => 'widget-button-update', 30 | 'options' => [ 31 | [ 32 | 'id' => 'save-button', 33 | 'label' => __('Save'), 34 | 'default' => true, 35 | 'data_attribute' => [ 36 | 'mage-init' => [ 37 | 'button' => [ 38 | 'event' => 'saveAndContinueEdit', 39 | 'target' => '#edit_form', 40 | ], 41 | ], 42 | ], 43 | ], 44 | [ 45 | 'id' => 'save-continue-button', 46 | 'label' => __('Save & Close'), 47 | 'data_attribute' => [ 48 | 'mage-init' => [ 49 | 'button' => [ 50 | 'event' => 'save', 51 | 'target' => '#edit_form', 52 | ], 53 | ], 54 | ], 55 | ], 56 | ], 57 | ] 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Block/Adminhtml/Post/Edit/Form.php: -------------------------------------------------------------------------------- 1 | formFactory = $formFactory; 31 | $this->context = $context; 32 | 33 | parent::__construct($context, $data); 34 | } 35 | 36 | /** 37 | * @return string 38 | */ 39 | public function getSaveUrl() 40 | { 41 | return $this->getUrl('*/*/save', ['id' => $this->getRequest()->getParam('id')]); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Block/Adminhtml/Post/Edit/Sidebar.php: -------------------------------------------------------------------------------- 1 | localeResolver = $localeResolver; 36 | $this->registry = $registry; 37 | 38 | parent::__construct($context); 39 | } 40 | 41 | /** 42 | * @return Post 43 | */ 44 | public function getPost() 45 | { 46 | return $this->registry->registry('current_model'); 47 | } 48 | 49 | /** 50 | * @param string $param 51 | * @param string $default 52 | * 53 | * @return string 54 | * @throws Zend_Locale_Exception 55 | */ 56 | public function getLocaleData($param, $default = '') 57 | { 58 | try { 59 | $text = Zend_Locale_Data::getContent($this->localeResolver->getLocale(), $param); 60 | } catch (Exception $e) { 61 | $text = $default; 62 | } 63 | 64 | return $text; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Block/Adminhtml/Post/Edit/Sidebar/Author.php: -------------------------------------------------------------------------------- 1 | authorSource = $authorSource; 43 | $this->formFactory = $formFactory; 44 | $this->registry = $registry; 45 | 46 | parent::__construct($context); 47 | } 48 | 49 | /** 50 | * @return $this 51 | * @throws LocalizedException 52 | */ 53 | protected function _prepareForm() 54 | { 55 | $form = $this->formFactory->create(); 56 | $this->setForm($form); 57 | 58 | /** @var Post $post */ 59 | $post = $this->registry->registry('current_model'); 60 | 61 | $fieldset = $form->addFieldset('tags_fieldset', [ 62 | 'class' => 'blog__post-fieldset', 63 | 'legend' => __('Author'), 64 | ]); 65 | 66 | $fieldset->addField('author_id', 'select', [ 67 | 'name' => 'post[author_id]', 68 | 'value' => $post->getAuthorId(), 69 | 'values' => $this->authorSource->toOptionArray(), 70 | ]); 71 | 72 | return parent::_prepareForm(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Block/Adminhtml/Post/Edit/Sidebar/Categories.php: -------------------------------------------------------------------------------- 1 | categoryCollectionFactory = $postCollectionFactory; 45 | $this->formFactory = $formFactory; 46 | $this->registry = $registry; 47 | 48 | parent::__construct($context, $data); 49 | } 50 | 51 | /** 52 | * @return $this 53 | * @throws LocalizedException 54 | */ 55 | protected function _prepareForm() 56 | { 57 | $form = $this->formFactory->create(); 58 | $this->setForm($form); 59 | 60 | /** @var Post $post */ 61 | $post = $this->registry->registry('current_model'); 62 | 63 | $fieldset = $form->addFieldset('categories_fieldset', [ 64 | 'class' => 'blog__post-fieldset', 65 | 'legend' => __('Categories'), 66 | ]); 67 | 68 | $collection = $this->categoryCollectionFactory->create() 69 | ->addAttributeToSelect(['name']); 70 | 71 | $fieldset->addField('category_ids', 'checkboxes', [ 72 | 'name' => 'post[category_ids][]', 73 | 'value' => $post->getCategoryIds(), 74 | 'values' => $collection->toOptionArray(), 75 | ]); 76 | 77 | return parent::_prepareForm(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Block/Adminhtml/Post/Edit/Sidebar/Image.php: -------------------------------------------------------------------------------- 1 | formFactory = $formFactory; 35 | $this->registry = $registry; 36 | 37 | parent::__construct($context); 38 | } 39 | 40 | /** 41 | * @return $this 42 | * @throws LocalizedException 43 | */ 44 | protected function _prepareForm() 45 | { 46 | $form = $this->formFactory->create(); 47 | $this->setForm($form); 48 | 49 | /** @var Post $post */ 50 | $post = $this->registry->registry('current_model'); 51 | 52 | $fieldset = $form->addFieldset('image_fieldset', [ 53 | 'class' => 'blog__post-fieldset', 54 | 'legend' => __('Featured Image'), 55 | ]); 56 | 57 | $fieldset->addField('featured_image', 'image', [ 58 | 'required' => false, 59 | 'name' => 'featured_image', 60 | 'value' => $post->getFeaturedImageUrl(), 61 | ]); 62 | 63 | $fieldset->addField('featured_alt', 'text', [ 64 | 'required' => false, 65 | 'label' => __('Alt'), 66 | 'name' => 'post[featured_alt]', 67 | 'value' => $post->getFeaturedAlt(), 68 | ]); 69 | 70 | $fieldset->addField('featured_show_on_home', 'checkbox', [ 71 | 'label' => __('Is show on Blog Home page'), 72 | 'name' => 'post[featured_show_on_home]', 73 | 'value' => 1, 74 | 'checked' => $post->getFeaturedShowOnHome(), 75 | ]); 76 | 77 | return parent::_prepareForm(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Block/Adminhtml/Post/Edit/Sidebar/Tags.php: -------------------------------------------------------------------------------- 1 | formFactory = $formFactory; 40 | $this->registry = $registry; 41 | 42 | parent::__construct($context); 43 | } 44 | 45 | /** 46 | * @return Collection 47 | */ 48 | public function getTags() 49 | { 50 | /** @var Post $post */ 51 | $post = $this->registry->registry('current_model'); 52 | 53 | return $post->getTags(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Block/Adminhtml/Post/Edit/Tab/Meta.php: -------------------------------------------------------------------------------- 1 | formFactory = $formFactory; 37 | $this->registry = $registry; 38 | $this->context = $context; 39 | 40 | parent::__construct($context, $data); 41 | } 42 | 43 | /** 44 | * @return $this 45 | * @throws LocalizedException 46 | */ 47 | protected function _prepareForm() 48 | { 49 | $form = $this->formFactory->create(); 50 | $this->setForm($form); 51 | 52 | /** @var Post $post */ 53 | $post = $this->registry->registry('current_model'); 54 | 55 | $fieldset = $form->addFieldset('edit_fieldset', [ 56 | 'class' => 'blog__post-fieldset', 57 | ]); 58 | 59 | $fieldset->addField('meta_title', 'text', [ 60 | 'label' => __('Meta Title'), 61 | 'name' => 'post[meta_title]', 62 | 'value' => $post->getMetaTitle(), 63 | ]); 64 | 65 | $fieldset->addField('meta_description', 'textarea', [ 66 | 'label' => __('Meta Description'), 67 | 'name' => 'post[meta_description]', 68 | 'value' => $post->getMetaDescription(), 69 | ]); 70 | 71 | $fieldset->addField('meta_keywords', 'textarea', [ 72 | 'label' => __('Meta Keywords'), 73 | 'name' => 'post[meta_keywords]', 74 | 'value' => $post->getMetaKeywords(), 75 | ]); 76 | 77 | $fieldset->addField('url_key', 'text', [ 78 | 'label' => __('URL Key'), 79 | 'name' => 'post[url_key]', 80 | 'value' => $post->getUrlKey(), 81 | ]); 82 | 83 | return parent::_prepareForm(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Block/Adminhtml/Post/Edit/Tabs.php: -------------------------------------------------------------------------------- 1 | setId('blog__post-tabs'); 14 | $this->setDestElementId('blog_details'); 15 | } 16 | 17 | /** 18 | * {@inheritdoc} 19 | */ 20 | protected function _beforeToHtml() 21 | { 22 | $this->addTab('general_section', [ 23 | 'label' => __('General Information'), 24 | 'content' => $this->getLayout() 25 | ->createBlock('Mirasvit\Blog\Block\Adminhtml\Post\Edit\Tab\General')->toHtml(), 26 | ]); 27 | 28 | $this->addTab('meta_section', [ 29 | 'label' => __('Search Engine Optimization'), 30 | 'content' => $this->getLayout() 31 | ->createBlock('Mirasvit\Blog\Block\Adminhtml\Post\Edit\Tab\Meta')->toHtml(), 32 | ]); 33 | 34 | $this->addTab('products_section', [ 35 | 'label' => __('Related Products'), 36 | 'content' => $this->getLayout() 37 | ->createBlock('Mirasvit\Blog\Block\Adminhtml\Post\Edit\Tab\Products')->toHtml(), 38 | ]); 39 | 40 | return parent::_beforeToHtml(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Block/Author/View.php: -------------------------------------------------------------------------------- 1 | registry = $registry; 34 | $this->context = $context; 35 | 36 | parent::__construct($context, $data); 37 | } 38 | 39 | /** 40 | * @return $this 41 | * @throws LocalizedException 42 | */ 43 | protected function _prepareLayout() 44 | { 45 | parent::_prepareLayout(); 46 | 47 | $author = $this->getAuthor(); 48 | 49 | if (!$author) { 50 | return $this; 51 | } 52 | 53 | $this->pageConfig->getTitle()->set(__('Author: %1', $author->getName())); 54 | 55 | if ($author && ($breadcrumbs = $this->getLayout()->getBlock('breadcrumbs'))) { 56 | $breadcrumbs->addCrumb('home', [ 57 | 'label' => __('Home'), 58 | 'title' => __('Go to Home Page'), 59 | 'link' => $this->context->getUrlBuilder()->getBaseUrl(), 60 | ]); 61 | 62 | $breadcrumbs->addCrumb('blog', [ 63 | 'label' => __('Blog'), 64 | 'title' => __('Blog'), 65 | ]); 66 | 67 | $breadcrumbs->addCrumb($author->getId(), [ 68 | 'label' => __('Author: %1', $author->getName()), 69 | 'title' => __('Author: %1', $author->getName()), 70 | ]); 71 | } 72 | 73 | return $this; 74 | } 75 | 76 | /** 77 | * @return Author 78 | */ 79 | public function getAuthor() 80 | { 81 | return $this->registry->registry('current_blog_author'); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Block/Html/Pager.php: -------------------------------------------------------------------------------- 1 | getUrl($this->getPath(), $urlParams); 34 | if ($this->getEntity()) { 35 | $path = $this->getEntity()->getUrl($urlParams); 36 | } elseif ($this->getRequest()->getControllerName() == 'search') { 37 | $url = ObjectManager::getInstance()->get('Mirasvit\Blog\Model\Url'); 38 | $urlParams['_current'] = true; 39 | $path = $url->getSearchUrl($urlParams); 40 | } 41 | 42 | return $path; 43 | } 44 | 45 | /** 46 | * @return string 47 | */ 48 | protected function getPath() 49 | { 50 | $config = ObjectManager::getInstance()->get('Mirasvit\Blog\Model\Config'); 51 | 52 | return $config->getBaseRoute(); 53 | } 54 | 55 | /** 56 | * @return UrlInterface|null 57 | */ 58 | public function getEntity() 59 | { 60 | return $this->entity; 61 | } 62 | 63 | /** 64 | * @param UrlInterface $entity 65 | * 66 | * @return $this 67 | */ 68 | public function setEntity($entity) 69 | { 70 | $this->entity = $entity; 71 | 72 | return $this; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Block/Post/AbstractBlock.php: -------------------------------------------------------------------------------- 1 | config = $config; 38 | $this->registry = $registry; 39 | $this->context = $context; 40 | 41 | parent::__construct($context); 42 | } 43 | 44 | /** 45 | * @param object|null $post 46 | * 47 | * @return Meta 48 | */ 49 | public function getPostMetaHeader($post = null) 50 | { 51 | /** @var Meta $block */ 52 | $block = $this->getLayout()->createBlock('Mirasvit\Blog\Block\Post\Meta'); 53 | 54 | $block->setTemplate('post/meta/header.phtml'); 55 | 56 | if ($post) { 57 | $block->setData('post', $post); 58 | } 59 | 60 | return $block; 61 | } 62 | 63 | /** 64 | * @param object|null $post 65 | * 66 | * @return Meta 67 | */ 68 | public function getPostMetaFooter($post = null) 69 | { 70 | /** @var Meta $block */ 71 | $block = $this->getLayout()->createBlock('Mirasvit\Blog\Block\Post\Meta'); 72 | 73 | $block->setTemplate('post/meta/footer.phtml'); 74 | 75 | if ($post) { 76 | $block->setData('post', $post); 77 | } 78 | 79 | return $block; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Block/Post/Meta.php: -------------------------------------------------------------------------------- 1 | hasData('post')) { 16 | return $this->getData('post'); 17 | } 18 | 19 | return $this->registry->registry('current_blog_post'); 20 | } 21 | 22 | /** 23 | * @return Category 24 | */ 25 | public function getCategory() 26 | { 27 | return $this->registry->registry('current_blog_category'); 28 | } 29 | 30 | /** 31 | * @return string 32 | */ 33 | public function getCommentProvider() 34 | { 35 | return $this->config->getCommentProvider(); 36 | } 37 | 38 | /** 39 | * @return string 40 | */ 41 | public function getDisqusShortname() 42 | { 43 | return $this->config->getDisqusShortname(); 44 | } 45 | 46 | /** 47 | * @param string $date 48 | * 49 | * @return string 50 | */ 51 | public function toDateFormat($date) 52 | { 53 | return date($this->config->getDateFormat(), strtotime($date)); 54 | } 55 | 56 | /** 57 | * @return bool 58 | */ 59 | public function isAddThisEnabled() 60 | { 61 | return $this->config->isAddThisEnabled(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Block/Post/Pinned.php: -------------------------------------------------------------------------------- 1 | postCollectionFactory = $postCollectionFactory; 42 | $this->registry = $registry; 43 | $this->context = $context; 44 | 45 | parent::__construct($context, $data); 46 | } 47 | 48 | /** 49 | * @return Post[] 50 | */ 51 | public function getCollection() 52 | { 53 | $collection = $this->postCollectionFactory->create() 54 | ->addAttributeToSelect(['name', 'featured_image', 'url_key']) 55 | ->addVisibilityFilter() 56 | ->addStoreFilter($this->context->getStoreManager()->getStore()->getId()) 57 | ->addAttributeToFilter('is_pinned', 1); 58 | 59 | if ($this->getCategory()) { 60 | $collection->addCategoryFilter($this->getCategory()); 61 | } 62 | 63 | return $collection; 64 | } 65 | 66 | /** 67 | * @return Category|false 68 | */ 69 | public function getCategory() 70 | { 71 | return $this->registry->registry('current_blog_category'); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Block/Post/View/RelatedPosts.php: -------------------------------------------------------------------------------- 1 | postCollectionFactory = $postCollectionFactory; 35 | $this->registry = $registry; 36 | 37 | parent::__construct($context); 38 | } 39 | 40 | /** 41 | * @return Collection 42 | */ 43 | public function getPostCollection() 44 | { 45 | $tags = $this->getCurrentPost()->getTagIds(); 46 | $collection = $this->postCollectionFactory->create() 47 | ->addTagFilter($tags) 48 | ->addFieldToFilter('entity_id', ['neq' => $this->getCurrentPost()->getId()]) 49 | ->addVisibilityFilter() 50 | ->addStoreFilter($this->_storeManager->getStore()->getId()) 51 | ->addAttributeToSelect('*'); 52 | 53 | return $collection; 54 | } 55 | 56 | /** 57 | * @return Post 58 | */ 59 | public function getCurrentPost() 60 | { 61 | return $this->registry->registry('current_blog_post'); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Block/Post/View/RelatedProducts.php: -------------------------------------------------------------------------------- 1 | registry = $context->getRegistry(); 25 | 26 | parent::__construct($context); 27 | } 28 | 29 | /** 30 | * @return Collection 31 | */ 32 | public function getRelatedProducts() 33 | { 34 | return $this->getCurrentPost()->getRelatedProducts(); 35 | } 36 | 37 | /** 38 | * @return Post 39 | */ 40 | public function getCurrentPost() 41 | { 42 | return $this->registry->registry('current_blog_post'); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Block/Sidebar/CategoryTree.php: -------------------------------------------------------------------------------- 1 | categoryCollectionFactory = $postCollectionFactory; 41 | $this->registry = $registry; 42 | $this->context = $context; 43 | 44 | parent::__construct($context, $data); 45 | } 46 | 47 | /** 48 | * @return Category[] 49 | */ 50 | public function getTree() 51 | { 52 | return $this->categoryCollectionFactory->create() 53 | ->addAttributeToSelect(['name', 'url_key']) 54 | ->addVisibilityFilter() 55 | ->excludeRoot() 56 | ->getTree(); 57 | } 58 | 59 | /** 60 | * @param Category $category 61 | * 62 | * @return bool 63 | */ 64 | public function isCurrent($category) 65 | { 66 | if ($this->getCurrentCategory() && $this->getCurrentCategory()->getId() == $category->getId()) { 67 | return true; 68 | } 69 | 70 | return false; 71 | } 72 | 73 | /** 74 | * @return Category|false 75 | */ 76 | public function getCurrentCategory() 77 | { 78 | return $this->registry->registry('current_blog_category'); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Block/Sidebar/Search.php: -------------------------------------------------------------------------------- 1 | url = $url; 27 | 28 | parent::__construct($context, $data); 29 | } 30 | 31 | /** 32 | * @return string 33 | */ 34 | public function getSearchUrl() 35 | { 36 | return $this->url->getSearchUrl(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Block/Sidebar/TagCloud.php: -------------------------------------------------------------------------------- 1 | tagCollectionFactory = $postCollectionFactory; 46 | $this->registry = $registry; 47 | $this->context = $context; 48 | 49 | parent::__construct($context, $data); 50 | } 51 | 52 | /** 53 | * @return int 54 | */ 55 | public function getMaxPopularity() 56 | { 57 | $max = 0; 58 | foreach ($this->getCollection() as $tag) { 59 | if ($tag->getPopularity() > $max) { 60 | $max = $tag->getPopularity(); 61 | } 62 | } 63 | 64 | return $max; 65 | } 66 | 67 | /** 68 | * @return Collection 69 | */ 70 | public function getCollection() 71 | { 72 | if (!$this->collection) { 73 | $storeId = $this->context->getStoreManager()->getStore()->getId(); 74 | $this->collection = $this->tagCollectionFactory->create(); 75 | $this->collection 76 | ->joinPopularity() 77 | ->addStoreFilter($storeId); 78 | } 79 | 80 | return $this->collection; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Block/Tag/View.php: -------------------------------------------------------------------------------- 1 | registry = $registry; 34 | $this->context = $context; 35 | 36 | parent::__construct($context, $data); 37 | } 38 | 39 | /** 40 | * @return $this 41 | * @throws LocalizedException 42 | */ 43 | protected function _prepareLayout() 44 | { 45 | parent::_prepareLayout(); 46 | 47 | $tag = $this->getTag(); 48 | if (!$tag) { 49 | return $this; 50 | } 51 | 52 | $this->pageConfig->getTitle()->set(__('Tag: %1', $tag->getName())); 53 | 54 | if ($tag && ($breadcrumbs = $this->getLayout()->getBlock('breadcrumbs'))) { 55 | $breadcrumbs->addCrumb('home', [ 56 | 'label' => __('Home'), 57 | 'title' => __('Go to Home Page'), 58 | 'link' => $this->context->getUrlBuilder()->getBaseUrl(), 59 | ]); 60 | 61 | $breadcrumbs->addCrumb('blog', [ 62 | 'label' => __('Blog'), 63 | 'title' => __('Blog'), 64 | ]); 65 | 66 | $breadcrumbs->addCrumb($tag->getId(), [ 67 | 'label' => __('Tag: %1', $tag->getName()), 68 | 'title' => __('Tag: %1', $tag->getName()), 69 | ]); 70 | } 71 | 72 | return $this; 73 | } 74 | 75 | /** 76 | * @return Tag 77 | */ 78 | public function getTag() 79 | { 80 | return $this->registry->registry('current_blog_tag'); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Author.php: -------------------------------------------------------------------------------- 1 | authorFactory = $authorFactory; 40 | $this->registry = $registry; 41 | $this->context = $context; 42 | 43 | parent::__construct($context); 44 | } 45 | 46 | /** 47 | * @return \Mirasvit\Blog\Model\Author 48 | */ 49 | public function initModel() 50 | { 51 | $model = $this->authorFactory->create(); 52 | if ($this->getRequest()->getParam('id')) { 53 | $model->load($this->getRequest()->getParam('id')); 54 | } 55 | 56 | $this->registry->register('current_model', $model); 57 | 58 | return $model; 59 | } 60 | 61 | /** 62 | * {@inheritdoc} 63 | * @param Page $resultPage 64 | * 65 | * @return Interceptor 66 | */ 67 | protected function initPage($resultPage) 68 | { 69 | $resultPage->setActiveMenu('Mirasvit_Blog::blog'); 70 | $resultPage->getConfig()->getTitle()->prepend(__('Mirasvit Blog MX')); 71 | $resultPage->getConfig()->getTitle()->prepend(__('Authors')); 72 | 73 | return $resultPage; 74 | } 75 | 76 | /** 77 | * @return bool 78 | */ 79 | protected function _isAllowed() 80 | { 81 | return $this->context->getAuthorization()->isAllowed('Mirasvit_Blog::blog_author'); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Author/Edit.php: -------------------------------------------------------------------------------- 1 | resultFactory->create(ResultFactory::TYPE_PAGE); 19 | 20 | $id = $this->getRequest()->getParam('id'); 21 | $model = $this->initModel(); 22 | 23 | if ($id && !$model->getId()) { 24 | $this->messageManager->addError(__('This author no longer exists.')); 25 | 26 | return $this->resultRedirectFactory->create()->setPath('*/*/'); 27 | } 28 | 29 | $this->initPage($resultPage)->getConfig()->getTitle()->prepend($model->getName()); 30 | 31 | return $resultPage; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Author/Index.php: -------------------------------------------------------------------------------- 1 | context->getResultFactory()->create(ResultFactory::TYPE_PAGE); 19 | 20 | $this->initPage($resultPage) 21 | ->getConfig()->getTitle()->prepend(__('Authors')); 22 | 23 | $this->_addContent($resultPage->getLayout() 24 | ->createBlock('Mirasvit\Blog\Block\Adminhtml\Author')); 25 | 26 | return $resultPage; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Author/Save.php: -------------------------------------------------------------------------------- 1 | getRequest()->getParam('id'); 16 | $resultRedirect = $this->resultRedirectFactory->create(); 17 | 18 | if ($data = $this->getRequest()->getParams()) { 19 | $model = $this->initModel(); 20 | 21 | if (!$model->getId() && $id) { 22 | $this->messageManager->addError(__('This author no longer exists.')); 23 | 24 | return $resultRedirect->setPath('*/*/'); 25 | } 26 | 27 | $model->addData($data); 28 | 29 | try { 30 | $model->save(); 31 | $this->messageManager->addSuccess(__('Author was successfully saved')); 32 | $this->context->getSession()->setFormData(false); 33 | 34 | if ($this->getRequest()->getParam('back')) { 35 | return $resultRedirect->setPath('*/*/edit', ['id' => $model->getId()]); 36 | } 37 | 38 | return $this->context->getResultRedirectFactory()->create()->setPath('*/*/'); 39 | } catch (Exception $e) { 40 | $this->messageManager->addErrorMessage($e->getMessage()); 41 | 42 | return $resultRedirect->setPath('*/*/edit', ['id' => $this->getRequest()->getParam('id')]); 43 | } 44 | } else { 45 | $resultRedirect->setPath('*/*/'); 46 | $this->messageManager->addError('No data to save.'); 47 | 48 | return $resultRedirect; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Category.php: -------------------------------------------------------------------------------- 1 | categoryFactory = $authorFactory; 40 | $this->registry = $registry; 41 | $this->context = $context; 42 | 43 | parent::__construct($context); 44 | } 45 | 46 | /** 47 | * @return \Mirasvit\Blog\Model\Category 48 | */ 49 | public function initModel() 50 | { 51 | $model = $this->categoryFactory->create(); 52 | if ($this->getRequest()->getParam('id')) { 53 | $model->load($this->getRequest()->getParam('id')); 54 | } 55 | 56 | $this->registry->register('current_model', $model); 57 | 58 | return $model; 59 | } 60 | 61 | /** 62 | * {@inheritdoc} 63 | * @param Page $resultPage 64 | * 65 | * @return Interceptor 66 | */ 67 | protected function initPage($resultPage) 68 | { 69 | $resultPage->setActiveMenu('Mirasvit_Blog::blog'); 70 | $resultPage->getConfig()->getTitle()->prepend(__('Mirasvit Blog MX')); 71 | $resultPage->getConfig()->getTitle()->prepend(__('Categories')); 72 | 73 | return $resultPage; 74 | } 75 | 76 | /** 77 | * @return bool 78 | */ 79 | protected function _isAllowed() 80 | { 81 | return $this->context->getAuthorization()->isAllowed('Mirasvit_Blog::blog_category'); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Category/Delete.php: -------------------------------------------------------------------------------- 1 | initModel(); 16 | 17 | $resultRedirect = $this->resultRedirectFactory->create(); 18 | 19 | if ($model->getId()) { 20 | try { 21 | $model->delete(); 22 | 23 | $this->messageManager->addSuccess(__('The category has been deleted.')); 24 | 25 | return $resultRedirect->setPath('*/*/'); 26 | } catch (Exception $e) { 27 | $this->messageManager->addError($e->getMessage()); 28 | 29 | return $resultRedirect->setPath('*/*/edit', ['id' => $model->getId()]); 30 | } 31 | } else { 32 | $this->messageManager->addError(__('This category no longer exists.')); 33 | 34 | return $resultRedirect->setPath('*/*/'); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Category/Edit.php: -------------------------------------------------------------------------------- 1 | resultFactory->create(ResultFactory::TYPE_PAGE); 19 | 20 | $id = $this->getRequest()->getParam('id'); 21 | $model = $this->initModel(); 22 | 23 | if ($id && !$model->getId()) { 24 | $this->messageManager->addError(__('This category no longer exists.')); 25 | 26 | return $this->resultRedirectFactory->create()->setPath('*/*/'); 27 | } 28 | 29 | $this->initPage($resultPage)->getConfig()->getTitle()->prepend($id ? $model->getName() : __('New Category')); 30 | 31 | return $resultPage; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Category/Index.php: -------------------------------------------------------------------------------- 1 | context->getResultFactory()->create(ResultFactory::TYPE_PAGE); 19 | 20 | $this->initPage($resultPage) 21 | ->getConfig()->getTitle()->prepend(__('Categories')); 22 | 23 | $this->_addContent($resultPage->getLayout() 24 | ->createBlock('\Mirasvit\Blog\Block\Adminhtml\Category')); 25 | 26 | return $resultPage; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Category/NewAction.php: -------------------------------------------------------------------------------- 1 | resultRedirectFactory->create()->setPath('*/*/edit'); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Category/Save.php: -------------------------------------------------------------------------------- 1 | getRequest()->getParam('id'); 16 | $resultRedirect = $this->resultRedirectFactory->create(); 17 | 18 | if ($data = $this->getRequest()->getParams()) { 19 | $model = $this->initModel(); 20 | 21 | if (!$model->getId() && $id) { 22 | $this->messageManager->addErrorMessage(__('This category no longer exists.')); 23 | 24 | return $resultRedirect->setPath('*/*/'); 25 | } 26 | 27 | $model->addData($data); 28 | 29 | try { 30 | $model->save(); 31 | $this->messageManager->addSuccessMessage(__('Category was successfully saved')); 32 | $this->context->getSession()->setFormData(false); 33 | 34 | if ($this->getRequest()->getParam('back')) { 35 | return $resultRedirect->setPath('*/*/edit', ['id' => $model->getId()]); 36 | } 37 | 38 | return $this->context->getResultRedirectFactory()->create()->setPath('*/*/'); 39 | } catch (Exception $e) { 40 | $this->messageManager->addErrorMessage($e->getMessage()); 41 | 42 | return $resultRedirect->setPath('*/*/edit', ['id' => $this->getRequest()->getParam('id')]); 43 | } 44 | } else { 45 | $resultRedirect->setPath('*/*/'); 46 | $this->messageManager->addErrorMessage('No data to save.'); 47 | 48 | return $resultRedirect; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Post/Delete.php: -------------------------------------------------------------------------------- 1 | initModel(); 17 | 18 | $resultRedirect = $this->resultRedirectFactory->create(); 19 | 20 | if ($model->getId()) { 21 | try { 22 | $this->postRepository->delete($model); 23 | 24 | $this->messageManager->addSuccessMessage(__('The post has been deleted.')); 25 | 26 | return $resultRedirect->setPath('*/*/'); 27 | } catch (Exception $e) { 28 | $this->messageManager->addErrorMessage($e->getMessage()); 29 | 30 | return $resultRedirect->setPath('*/*/edit', [PostInterface::ID => $model->getId()]); 31 | } 32 | } else { 33 | $this->messageManager->addErrorMessage(__('This post no longer exists.')); 34 | 35 | return $resultRedirect->setPath('*/*/'); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Post/Edit.php: -------------------------------------------------------------------------------- 1 | resultFactory->create(ResultFactory::TYPE_PAGE); 20 | 21 | $id = $this->getRequest()->getParam(PostInterface::ID); 22 | $model = $this->initModel(); 23 | 24 | if ($id && !is_array($id) && !$model->getId()) { 25 | $this->messageManager->addErrorMessage(__('This post no longer exists.')); 26 | 27 | return $this->resultRedirectFactory->create()->setPath('*/*/'); 28 | } 29 | 30 | $this->initPage($resultPage)->getConfig()->getTitle()->prepend( 31 | $model->getName() ? $model->getName() : __('New Post') 32 | ); 33 | 34 | return $resultPage; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Post/FileUpload.php: -------------------------------------------------------------------------------- 1 | fileProcessor = $fileProcessor; 26 | 27 | parent::__construct($postRepository, $registry, $context); 28 | } 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function execute() 34 | { 35 | $result = $this->fileProcessor->save(key($_FILES)); 36 | 37 | return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData($result); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Post/Index.php: -------------------------------------------------------------------------------- 1 | resultFactory->create(ResultFactory::TYPE_PAGE); 18 | 19 | $this->initPage($resultPage) 20 | ->getConfig() 21 | ->getTitle() 22 | ->prepend(__('All Posts')); 23 | 24 | return $resultPage; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Post/InlineEdit.php: -------------------------------------------------------------------------------- 1 | jsonFactory = $jsonFactory; 27 | 28 | parent::__construct($postRepository, $registry, $context); 29 | } 30 | 31 | /** 32 | * {@inheritdoc} 33 | */ 34 | public function execute() 35 | { 36 | /** @var Json $resultJson */ 37 | $resultJson = $this->jsonFactory->create(); 38 | 39 | $error = false; 40 | $messages = []; 41 | 42 | $postItems = $this->getRequest()->getParam('items', []); 43 | if (!($this->getRequest()->getParam('isAjax') && count($postItems))) { 44 | return $resultJson->setData([ 45 | 'messages' => [__('Please correct the data sent.')], 46 | 'error' => true, 47 | ]); 48 | } 49 | 50 | foreach (array_keys($postItems) as $postId) { 51 | $post = $this->postRepository->get($postId); 52 | 53 | try { 54 | $data = $postItems[$postId]; 55 | 56 | //@todo 57 | $post->addData($data); 58 | 59 | $this->postRepository->save($post); 60 | } catch (Exception $e) { 61 | $messages[] = __('Something went wrong while saving the post.'); 62 | $error = true; 63 | } 64 | } 65 | 66 | return $resultJson->setData([ 67 | 'messages' => $messages, 68 | 'error' => $error, 69 | ]); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Post/MassDelete.php: -------------------------------------------------------------------------------- 1 | filter = $filter; 21 | $this->collectionFactory = $collectionFactory; 22 | parent::__construct($context); 23 | } 24 | 25 | public function execute() 26 | { 27 | $collection = $this->filter->getCollection($this->collectionFactory->create()); 28 | $collectionSize = $collection->getSize(); 29 | 30 | foreach ($collection as $item) { 31 | $item->delete(); 32 | } 33 | 34 | $this->messageManager->addSuccess(__('A total of %1 post(s) have been deleted.', $collectionSize)); 35 | 36 | /** 37 | * @var Redirect $resultRedirect 38 | */ 39 | $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); 40 | 41 | return $resultRedirect->setPath('*/*/'); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Post/MassStatus.php: -------------------------------------------------------------------------------- 1 | filter = $filter; 37 | $this->collectionFactory = $collectionFactory; 38 | parent::__construct($context); 39 | } 40 | 41 | /** 42 | * Execute action 43 | * @return Redirect 44 | * @throws LocalizedException|Exception 45 | */ 46 | public function execute() 47 | { 48 | $statusValue = $this->getRequest()->getParam('status'); 49 | $collection = $this->filter->getCollection($this->collectionFactory->create()); 50 | 51 | foreach ($collection as $item) { 52 | $item->setStatus($statusValue); 53 | $item->save(); 54 | } 55 | 56 | $this->messageManager->addSuccess(__('A total of %1 record(s) have been modified.', $collection->getSize())); 57 | 58 | /** @var Redirect $resultRedirect */ 59 | $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); 60 | 61 | return $resultRedirect->setPath('*/*/'); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Post/NewAction.php: -------------------------------------------------------------------------------- 1 | resultRedirectFactory->create()->setPath('*/*/edit'); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Post/RelatedProductsGrid.php: -------------------------------------------------------------------------------- 1 | initModel(); 15 | $this->_view->loadLayout() 16 | ->getLayout() 17 | ->getBlock('blog.post.tab.products') 18 | ->setProductsRelated($this->getRequest()->getPost('products_related')); 19 | $this->_view->renderLayout(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Controller/Author/View.php: -------------------------------------------------------------------------------- 1 | authorFactory = $authorFactory; 41 | $this->registry = $registry; 42 | $this->resultFactory = $context->getResultFactory(); 43 | 44 | parent::__construct($context); 45 | } 46 | 47 | /** 48 | * @return Page 49 | */ 50 | public function execute() 51 | { 52 | if ($this->initModel()) { 53 | /* @var Page $resultPage */ 54 | $resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE); 55 | 56 | return $resultPage; 57 | } else { 58 | $this->_forward('no_route'); 59 | } 60 | } 61 | 62 | /** 63 | * @return Author 64 | */ 65 | protected function initModel() 66 | { 67 | if ($id = $this->getRequest()->getParam('id')) { 68 | $author = $this->authorFactory->create()->load($id); 69 | if ($author->getId() > 0) { 70 | $this->registry->register('current_blog_author', $author); 71 | 72 | return $author; 73 | } 74 | } 75 | 76 | return false; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Controller/Category.php: -------------------------------------------------------------------------------- 1 | categoryFactory = $authorFactory; 29 | $this->registry = $registry; 30 | $this->context = $context; 31 | $this->resultFactory = $context->getResultFactory(); 32 | 33 | parent::__construct($context); 34 | } 35 | 36 | /** 37 | * @return \Mirasvit\Blog\Model\Category 38 | */ 39 | protected function initCategory() 40 | { 41 | if ($id = $this->getRequest()->getParam(CategoryInterface::ID)) { 42 | $post = $this->categoryFactory->create()->load($id); 43 | if ($post->getId() > 0) { 44 | $this->registry->register('current_blog_category', $post); 45 | 46 | return $post; 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Controller/Category/Index.php: -------------------------------------------------------------------------------- 1 | resultFactory->create(ResultFactory::TYPE_PAGE); 17 | 18 | return $resultPage; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Controller/Category/Rss.php: -------------------------------------------------------------------------------- 1 | _view->getLayout()->createBlock('Mirasvit\Blog\Block\Category\Rss') 15 | ->setTemplate('category/rss.phtml') 16 | ->toHtml(); 17 | 18 | $this->getResponse() 19 | ->setHeader('Content-type', 'text/xml') 20 | ->setBody($rss); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Controller/Category/View.php: -------------------------------------------------------------------------------- 1 | initCategory()) { 17 | /* @var Page $resultPage */ 18 | $resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE); 19 | 20 | return $resultPage; 21 | } else { 22 | $this->_forward('no_route'); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Controller/Post.php: -------------------------------------------------------------------------------- 1 | storeManager = $storeManager; 31 | $this->postFactory = $authorFactory; 32 | $this->registry = $registry; 33 | $this->context = $context; 34 | $this->resultFactory = $context->getResultFactory(); 35 | 36 | parent::__construct($context); 37 | } 38 | 39 | /** 40 | * @return \Mirasvit\Blog\Model\Post|boolean 41 | */ 42 | protected function initModel() 43 | { 44 | $id = $this->getRequest()->getParam(PostInterface::ID); 45 | if (!$id) { 46 | return false; 47 | } 48 | 49 | $post = $this->postFactory->create()->load($id); 50 | 51 | if (!$post->getId()) { 52 | return false; 53 | } 54 | 55 | $this->registry->register('current_blog_post', $post); 56 | 57 | return $post; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Controller/Post/View.php: -------------------------------------------------------------------------------- 1 | initModel(); 20 | 21 | if (!$post) { 22 | throw new NotFoundException(__('Page not found')); 23 | die; 24 | } 25 | 26 | /* @var Page $resultPage */ 27 | $resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE); 28 | 29 | $this->_eventManager->dispatch( 30 | 'blog_page_render', 31 | ['post' => $post, 'controller_action' => $this] 32 | ); 33 | 34 | return $resultPage; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Controller/Router.php: -------------------------------------------------------------------------------- 1 | url = $url; 38 | $this->actionFactory = $actionFactory; 39 | $this->eventManager = $eventManager; 40 | } 41 | 42 | /** 43 | * {@inheritdoc} 44 | */ 45 | public function match(RequestInterface $request) 46 | { 47 | /** @var Http $request */ 48 | 49 | $identifier = trim($request->getPathInfo(), '/'); 50 | $this->eventManager->dispatch('core_controller_router_match_before', [ 51 | 'router' => $this, 52 | 'condition' => new DataObject(['identifier' => $identifier, 'continue' => true]), 53 | ]); 54 | 55 | $pathInfo = $request->getPathInfo(); 56 | 57 | $result = $this->url->match($pathInfo); 58 | 59 | if ($result) { 60 | $params = $result->getParams(); 61 | 62 | $request 63 | ->setModuleName($result->getModuleName()) 64 | ->setControllerName($result->getControllerName()) 65 | ->setActionName($result->getActionName()) 66 | ->setParams($params); 67 | 68 | return $this->actionFactory->create( 69 | 'Magento\Framework\App\Action\Forward', 70 | ['request' => $request] 71 | ); 72 | } 73 | 74 | return false; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Controller/Search/Result.php: -------------------------------------------------------------------------------- 1 | resultFactory->create(ResultFactory::TYPE_PAGE); 17 | 18 | return $resultPage; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Controller/Tag/View.php: -------------------------------------------------------------------------------- 1 | tagFactory = $authorFactory; 41 | $this->registry = $registry; 42 | $this->resultFactory = $context->getResultFactory(); 43 | 44 | parent::__construct($context); 45 | } 46 | 47 | /** 48 | * @return Page 49 | */ 50 | public function execute() 51 | { 52 | if ($this->initModel()) { 53 | /* @var Page $resultPage */ 54 | $resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE); 55 | 56 | return $resultPage; 57 | } else { 58 | $this->_forward('no_route'); 59 | } 60 | } 61 | 62 | /** 63 | * @return Tag 64 | */ 65 | protected function initModel() 66 | { 67 | if ($id = $this->getRequest()->getParam('id')) { 68 | $tag = $this->tagFactory->create()->load($id); 69 | if ($tag->getId() > 0) { 70 | $this->registry->register('current_blog_tag', $tag); 71 | 72 | return $tag; 73 | } 74 | } 75 | 76 | return false; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Helper/Category.php: -------------------------------------------------------------------------------- 1 | categoryCollectionFactory = $categoryCollectionFactory; 21 | 22 | parent::__construct($context); 23 | } 24 | 25 | /** 26 | * @return \Mirasvit\Blog\Model\Category|false 27 | */ 28 | public function getRootCategory() 29 | { 30 | $category = false; 31 | $collection = $this->categoryCollectionFactory->create() 32 | ->addFieldToFilter('parent_id', 0); 33 | 34 | if ($collection->count()) { 35 | $category = $collection->getFirstItem(); 36 | } 37 | 38 | return $category; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Model/Author.php: -------------------------------------------------------------------------------- 1 | getId()]; 25 | } 26 | 27 | /** 28 | * @param array $urlParams 29 | * 30 | * @return string 31 | */ 32 | public function getUrl($urlParams = []) 33 | { 34 | /** @var Url $url */ 35 | $url = ObjectManager::getInstance()->get('Mirasvit\Blog\Model\Url'); 36 | 37 | return $url->getAuthorUrl($this, $urlParams); 38 | } 39 | 40 | /** 41 | * {@inheritdoc} 42 | */ 43 | public function afterSave() 44 | { 45 | return parent::afterSave(); // TODO: Change the autogenerated stub 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Model/Config/Source/CommentProvider.php: -------------------------------------------------------------------------------- 1 | toOptionArray(); 13 | } 14 | 15 | /** 16 | * @return array 17 | */ 18 | public function toOptionArray() 19 | { 20 | $result = [ 21 | [ 22 | 'label' => __('Disable comments'), 23 | 'value' => '', 24 | ], 25 | [ 26 | 'label' => 'Disqus', 27 | 'value' => 'disqus', 28 | ], 29 | [ 30 | 'label' => 'Facebook', 31 | 'value' => 'facebook', 32 | ], 33 | ]; 34 | 35 | return $result; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Model/Post/Attribute/Source/Author.php: -------------------------------------------------------------------------------- 1 | userCollectionFactory = $userCollectionFactory; 24 | } 25 | 26 | /** 27 | * Retrieve option array with empty value 28 | * @return string[] 29 | */ 30 | public function getAllOptions() 31 | { 32 | $result = []; 33 | 34 | foreach ($this->getOptionArray() as $index => $value) { 35 | $result[] = ['value' => $index, 'label' => $value]; 36 | } 37 | 38 | return $result; 39 | } 40 | 41 | /** 42 | * Retrieve option array 43 | * @return string[] 44 | */ 45 | public function getOptionArray() 46 | { 47 | $result = []; 48 | foreach ($this->userCollectionFactory->create() as $user) { 49 | $result[$user->getId()] = $user->getName(); 50 | } 51 | 52 | return $result; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Model/Post/Attribute/Source/Status.php: -------------------------------------------------------------------------------- 1 | $value) { 35 | $result[] = ['value' => $index, 'label' => $value]; 36 | } 37 | 38 | return $result; 39 | } 40 | 41 | /** 42 | * Retrieve option array 43 | * @return string[] 44 | */ 45 | public static function getOptionArray() 46 | { 47 | return [ 48 | self::STATUS_DRAFT => __('Draft'), 49 | self::STATUS_PENDING_REVIEW => __('Pending Review'), 50 | self::STATUS_PUBLISHED => __('Published'), 51 | ]; 52 | } 53 | 54 | /** 55 | * Retrieve option text by option value 56 | * 57 | * @param string $optionId 58 | * 59 | * @return string 60 | */ 61 | public function getOptionText($optionId) 62 | { 63 | $options = self::getOptionArray(); 64 | 65 | return isset($options[$optionId]) ? $options[$optionId] : null; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Model/Post/PostList/Toolbar.php: -------------------------------------------------------------------------------- 1 | request = $request; 50 | } 51 | 52 | /** 53 | * Get sort order 54 | * @return string|bool 55 | */ 56 | public function getOrder() 57 | { 58 | return $this->request->getParam(self::ORDER_PARAM_NAME); 59 | } 60 | 61 | /** 62 | * Get sort direction 63 | * @return string|bool 64 | */ 65 | public function getDirection() 66 | { 67 | return $this->request->getParam(self::DIRECTION_PARAM_NAME); 68 | } 69 | 70 | /** 71 | * Get sort mode 72 | * @return string|bool 73 | */ 74 | public function getMode() 75 | { 76 | return $this->request->getParam(self::MODE_PARAM_NAME); 77 | } 78 | 79 | /** 80 | * Get products per page limit 81 | * @return string|bool 82 | */ 83 | public function getLimit() 84 | { 85 | return $this->request->getParam(self::LIMIT_PARAM_NAME); 86 | } 87 | 88 | /** 89 | * Return current page from request 90 | * @return int 91 | */ 92 | public function getCurrentPage() 93 | { 94 | $page = (int)$this->request->getParam(self::PAGE_PARM_NAME); 95 | 96 | return $page ? $page : 1; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Model/ResourceModel/Tag.php: -------------------------------------------------------------------------------- 1 | config = $config; 36 | $this->filter = $filter; 37 | 38 | parent::__construct($context, $connectionName); 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | */ 44 | protected function _construct() 45 | { 46 | $this->_init('mst_blog_tag', 'tag_id'); 47 | } 48 | 49 | /** 50 | * {@inheritdoc} 51 | */ 52 | protected function _beforeSave(AbstractModel $tag) 53 | { 54 | /** @var \Mirasvit\Blog\Model\Tag $tag */ 55 | 56 | if (!$tag->getData('url_key')) { 57 | $tag->setData('url_key', $this->filter->translitUrl($tag->getName())); 58 | } 59 | 60 | return parent::_beforeSave($tag); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Model/ResourceModel/Tag/Collection.php: -------------------------------------------------------------------------------- 1 | getSelect() 15 | ->joinLeft( 16 | ['tag_post' => $this->getTable('mst_blog_tag_post')], 17 | 'main_table.tag_id = tag_post.tag_id', 18 | ['popularity' => 'count(tag_post.tag_id)'] 19 | )->group('main_table.tag_id'); 20 | 21 | return $this; 22 | } 23 | 24 | /** 25 | * @return $this 26 | */ 27 | public function addStoreFilter($storeId) 28 | { 29 | $this->getSelect() 30 | ->joinLeft( 31 | ['store_post' => $this->getTable('mst_blog_store_post')], 32 | 'tag_post.post_id = store_post.post_id' 33 | )->where("EXISTS (SELECT * FROM `{$this->getTable('mst_blog_store_post')}` 34 | AS `store_post` 35 | WHERE tag_post.post_id = store_post.post_id 36 | AND store_post.store_id in (?)) 37 | OR NOT EXISTS (SELECT * FROM `{$this->getTable('mst_blog_store_post')}` 38 | AS `store_post` 39 | WHERE tag_post.post_id = store_post.post_id)", [0, $storeId]); 40 | 41 | return $this; 42 | } 43 | 44 | /** 45 | * @return $this 46 | */ 47 | public function joinNotEmptyFields() 48 | { 49 | $select = $this->getSelect(); 50 | $select->joinRight( 51 | ['article_tag' => $this->getTable('mst_kb_article_tag')], 52 | 'main_table.tag_id = at_tag_id', 53 | ['ratio' => 'count(main_table.tag_id)'] 54 | ) 55 | ->group('tag_id'); 56 | 57 | return $this; 58 | } 59 | 60 | /** 61 | * {@inheritdoc} 62 | */ 63 | protected function _construct() 64 | { 65 | $this->_init('Mirasvit\Blog\Model\Tag', 'Mirasvit\Blog\Model\ResourceModel\Tag'); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Model/Tag.php: -------------------------------------------------------------------------------- 1 | url = $url; 31 | 32 | parent::__construct($context, $registry); 33 | } 34 | 35 | /** 36 | * Get identities. 37 | * @return array 38 | */ 39 | public function getIdentities() 40 | { 41 | return [self::CACHE_TAG . '_' . $this->getId()]; 42 | } 43 | 44 | /** 45 | * {@inheritdoc} 46 | */ 47 | public function setName($value) 48 | { 49 | return $this->setData(self::NAME, $value); 50 | } 51 | 52 | /** 53 | * {@inheritdoc} 54 | */ 55 | public function getName() 56 | { 57 | return $this->getData(self::NAME); 58 | } 59 | 60 | /** 61 | * {@inheritdoc} 62 | */ 63 | public function setUrlKey($value) 64 | { 65 | return $this->setData(self::URL_KEY, $value); 66 | } 67 | 68 | /** 69 | * {@inheritdoc} 70 | */ 71 | public function getUrlKey() 72 | { 73 | return $this->getData(self::URL_KEY); 74 | } 75 | 76 | /** 77 | * @param array $urlParams 78 | * 79 | * @return string 80 | */ 81 | public function getUrl($urlParams = []) 82 | { 83 | return $this->url->getTagUrl($this, $urlParams); 84 | } 85 | 86 | // /** 87 | // * @param string $tag 88 | // * @return $this 89 | // */ 90 | // public function getOrCreate($tag) 91 | // { 92 | // $tag = trim($tag); 93 | // $this->load($tag, 'name'); 94 | // 95 | // if (!$this->getId()) { 96 | // $this->setName($tag) 97 | // ->save(); 98 | // } 99 | // 100 | // return $this; 101 | // } 102 | 103 | /** 104 | * {@inheritdoc} 105 | */ 106 | protected function _construct() 107 | { 108 | $this->_init('Mirasvit\Blog\Model\ResourceModel\Tag'); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /Model/UrlInterface.php: -------------------------------------------------------------------------------- 1 | factory = $factory; 20 | $this->collectionFactory = $collectionFactory; 21 | } 22 | 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function getCollection() 27 | { 28 | return $this->collectionFactory->create(); 29 | } 30 | 31 | /** 32 | * {@inheritdoc} 33 | */ 34 | public function get($id) 35 | { 36 | $user = $this->factory->create()->load($id); 37 | 38 | return $user->getId() ? $user : false; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Repository/CategoryRepository.php: -------------------------------------------------------------------------------- 1 | factory = $factory; 22 | $this->collectionFactory = $collectionFactory; 23 | } 24 | 25 | /** 26 | * {@inheritdoc} 27 | */ 28 | public function getCollection() 29 | { 30 | return $this->collectionFactory->create(); 31 | } 32 | 33 | /** 34 | * {@inheritdoc} 35 | */ 36 | public function get($id) 37 | { 38 | /** @var Category $model */ 39 | $model = $this->create(); 40 | 41 | $model->getResource()->load($model, $id); 42 | 43 | return $model->getId() ? $model : false; 44 | } 45 | 46 | /** 47 | * {@inheritdoc} 48 | */ 49 | public function create() 50 | { 51 | return $this->factory->create(); 52 | } 53 | 54 | /** 55 | * {@inheritdoc} 56 | */ 57 | public function delete(CategoryInterface $model) 58 | { 59 | /** @var Category $model */ 60 | return $model->getResource()->delete($model); 61 | } 62 | 63 | /** 64 | * {@inheritdoc} 65 | */ 66 | public function save(CategoryInterface $model) 67 | { 68 | /** @var Category $model */ 69 | return $model->getResource()->save($model); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Repository/TagRepository.php: -------------------------------------------------------------------------------- 1 | factory = $factory; 26 | $this->collectionFactory = $collectionFactory; 27 | $this->filterManager = $filterManager; 28 | } 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function get($id) 34 | { 35 | /** @var Tag $model */ 36 | $model = $this->create(); 37 | 38 | $model->getResource()->load($model, $id); 39 | 40 | return $model->getId() ? $model : false; 41 | } 42 | 43 | /** 44 | * {@inheritdoc} 45 | */ 46 | public function create() 47 | { 48 | return $this->factory->create(); 49 | } 50 | 51 | /** 52 | * {@inheritdoc} 53 | */ 54 | public function delete(TagInterface $model) 55 | { 56 | /** @var Tag $model */ 57 | return $model->getResource()->delete($model); 58 | } 59 | 60 | public function ensure(TagInterface $model) 61 | { 62 | /** @var TagInterface $tag */ 63 | $tag = $this->getCollection() 64 | ->addFieldToFilter(TagInterface::NAME, $model->getName()) 65 | ->getFirstItem(); 66 | 67 | if ($tag->getId()) { 68 | return $tag; 69 | } else { 70 | return $this->save($model); 71 | } 72 | } 73 | 74 | /** 75 | * {@inheritdoc} 76 | */ 77 | public function getCollection() 78 | { 79 | return $this->collectionFactory->create(); 80 | } 81 | 82 | /** 83 | * {@inheritdoc} 84 | */ 85 | public function save(TagInterface $model) 86 | { 87 | if (!$model->getUrlKey()) { 88 | $model->setUrlKey($this->filterManager->translitUrl($model->getName())); 89 | } 90 | 91 | /** @var Tag $model */ 92 | $model->getResource()->save($model); 93 | 94 | return $model; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Setup/InstallData.php: -------------------------------------------------------------------------------- 1 | postSetupFactory = $postSetupFactory; 40 | $this->categorySetupFactory = $categorySetupFactory; 41 | $this->eavConfig = $eavConfig; 42 | } 43 | 44 | /** 45 | * {@inheritdoc} 46 | */ 47 | public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context) 48 | { 49 | $setup->startSetup(); 50 | 51 | $postSetup = $this->postSetupFactory->create(['setup' => $setup]); 52 | $postSetup->installEntities(); 53 | 54 | $categorySetup = $this->categorySetupFactory->create(['setup' => $setup]); 55 | $categorySetup->installEntities(); 56 | 57 | $setup->endSetup(); 58 | 59 | $this->eavConfig->clear(); 60 | 61 | $category = $categorySetup->getCategoryFactory()->create(); 62 | $category 63 | ->setName(__('Blog')) 64 | ->setParentId(null) 65 | ->setPath('1') 66 | ->setLevel(0) 67 | ->setPosition(0) 68 | ->setStatus(1) 69 | ->save(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Setup/UpgradeData.php: -------------------------------------------------------------------------------- 1 | postSetupFactory = $postSetupFactory; 18 | $this->eavSetupFactory = $eavSetupFactory; 19 | } 20 | 21 | /** 22 | * {@inheritdoc} 23 | * @SuppressWarnings(PHPMD.ExcessiveMethodLength) 24 | */ 25 | public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context) 26 | { 27 | $setup->startSetup(); 28 | if (version_compare($context->getVersion(), '1.0.5') < 0) { 29 | /** @var PostSetup $postSetup */ 30 | $postSetup = $this->postSetupFactory->create(['setup' => $setup]); 31 | foreach ($this->getAttributes() as $code => $data) { 32 | $postSetup->addAttribute('blog_post', $code, $data); 33 | } 34 | } 35 | 36 | $setup->endSetup(); 37 | } 38 | 39 | /** 40 | * @return array 41 | */ 42 | private function getAttributes() 43 | { 44 | return [ 45 | 'featured_alt' => [ 46 | 'type' => 'varchar', 47 | 'label' => 'Alt', 48 | 'input' => 'text', 49 | 'global' => ScopedAttributeInterface::SCOPE_STORE, 50 | ], 51 | 'featured_show_on_home' => [ 52 | 'type' => 'int', 53 | 'label' => 'Is show on Blog Home page', 54 | 'input' => 'text', 55 | 'global' => ScopedAttributeInterface::SCOPE_STORE, 56 | 'default' => 1, 57 | ], 58 | ]; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Setup/Upgrade_1_0_4.php: -------------------------------------------------------------------------------- 1 | getConnection()->addColumn( 23 | $installer->getTable('mst_blog_category_entity'), 24 | 'sort_order', 25 | [ 26 | 'type' => Table::TYPE_INTEGER, 27 | 'length' => null, 28 | 'unsigned' => true, 29 | 'nullable' => false, 30 | 'default' => 0, 31 | 'comment' => 'Order', 32 | ] 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Ui/Component/Listing/Column/PostActions.php: -------------------------------------------------------------------------------- 1 | urlBuilder = $urlBuilder; 42 | $this->actionUrlBuilder = $actionUrlBuilder; 43 | $this->editUrl = $editUrl; 44 | 45 | parent::__construct($context, $uiComponentFactory, $components, $data); 46 | } 47 | 48 | /** 49 | * Prepare Data Source 50 | * 51 | * @param array $dataSource 52 | * 53 | * @return array 54 | */ 55 | public function prepareDataSource(array $dataSource) 56 | { 57 | if (isset($dataSource['data']['items'])) { 58 | foreach ($dataSource['data']['items'] as &$item) { 59 | $name = $this->getData('name'); 60 | if (isset($item[PostInterface::ID])) { 61 | $item[$name]['edit'] = [ 62 | 'href' => $this->urlBuilder->getUrl($this->editUrl, [ 63 | PostInterface::ID => $item[PostInterface::ID], 64 | ]), 65 | 'label' => __('Edit'), 66 | ]; 67 | } 68 | } 69 | } 70 | 71 | return $dataSource; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Ui/Post/Form/Control/BackButton.php: -------------------------------------------------------------------------------- 1 | __('Back'), 16 | 'on_click' => sprintf("location.href = '%s';", $this->getBackUrl()), 17 | 'class' => 'back', 18 | 'sort_order' => 10, 19 | ]; 20 | } 21 | 22 | /** 23 | * @return string 24 | */ 25 | public function getBackUrl() 26 | { 27 | return $this->getUrl('*/*/'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Ui/Post/Form/Control/DeleteButton.php: -------------------------------------------------------------------------------- 1 | getId()) { 17 | $data = [ 18 | 'label' => __('Delete'), 19 | 'class' => 'delete', 20 | 'on_click' => 'deleteConfirm(\'' . __( 21 | 'Are you sure you want to do this?' 22 | ) . '\', \'' . $this->getDeleteUrl() . '\')', 23 | 'sort_order' => 20, 24 | ]; 25 | } 26 | 27 | return $data; 28 | } 29 | 30 | /** 31 | * @return string 32 | */ 33 | public function getDeleteUrl() 34 | { 35 | return $this->getUrl('*/*/delete', [PostInterface::ID => $this->getId()]); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Ui/Post/Form/Control/GenericButton.php: -------------------------------------------------------------------------------- 1 | context = $context; 20 | } 21 | 22 | /** 23 | * @return int|null 24 | */ 25 | public function getId() 26 | { 27 | return $this->context->getRequest()->getParam(PostInterface::ID); 28 | } 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function getUrl($route = '', $params = []) 34 | { 35 | return $this->context->getUrlBuilder()->getUrl($route, $params); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Ui/Post/Form/Control/PreviewButton.php: -------------------------------------------------------------------------------- 1 | __('Preview'), 16 | 'class' => 'preview', 17 | 'on_click' => '', 18 | 'sort_order' => 0, 19 | ]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Ui/Post/Form/Control/SaveAndContinueButton.php: -------------------------------------------------------------------------------- 1 | __('Save and Continue Edit'), 17 | 'class' => 'save', 18 | 'data_attribute' => [ 19 | 'mage-init' => [ 20 | 'button' => ['event' => 'saveAndContinueEdit'], 21 | ], 22 | ], 23 | 'sort_order' => 80, 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Ui/Post/Form/Control/SaveButton.php: -------------------------------------------------------------------------------- 1 | __('Save'), 16 | 'class' => 'save primary', 17 | 'data_attribute' => [ 18 | 'mage-init' => ['button' => ['event' => 'save']], 19 | 'form-role' => 'save', 20 | ], 21 | 'sort_order' => 90, 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Ui/Post/Form/ProductDataProvider.php: -------------------------------------------------------------------------------- 1 | addAttributeToSelect('status'); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Ui/Post/Source/Author.php: -------------------------------------------------------------------------------- 1 | authorRepository = $authorRepository; 20 | } 21 | 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public function toOptionArray() 26 | { 27 | $result = []; 28 | foreach ($this->authorRepository->getCollection() as $user) { 29 | $result[] = [ 30 | 'label' => $user->getName(), 31 | 'value' => $user->getId(), 32 | ]; 33 | } 34 | 35 | return $result; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Ui/Post/Source/CategoryTree.php: -------------------------------------------------------------------------------- 1 | categoryRepository = $categoryRepository; 17 | } 18 | 19 | /** 20 | * {@inheritdoc} 21 | */ 22 | public function toOptionArray() 23 | { 24 | $collection = $this->categoryRepository->getCollection(); 25 | $rootId = $collection->getRootId(); 26 | 27 | return [$this->getOptions($rootId)]; 28 | } 29 | 30 | /** 31 | * @param int $parentId 32 | * 33 | * @return array 34 | */ 35 | private function getOptions($parentId) 36 | { 37 | $category = $this->categoryRepository->get($parentId); 38 | 39 | $data = [ 40 | 'label' => $category->getName(), 41 | 'value' => $category->getId(), 42 | ]; 43 | 44 | $collection = $this->categoryRepository->getCollection() 45 | ->addFieldToFilter(CategoryInterface::PARENT_ID, $category->getId()) 46 | ->setOrder(CategoryInterface::POSITION, 'asc'); 47 | 48 | /** @var CategoryInterface $item */ 49 | foreach ($collection as $item) { 50 | $data['optgroup'][] = $this->getOptions($item->getId()); 51 | } 52 | 53 | return $data; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Ui/Post/Source/Status.php: -------------------------------------------------------------------------------- 1 | __('Draft'), 18 | 'value' => PostInterface::STATUS_DRAFT, 19 | ], 20 | [ 21 | 'label' => __('Pending Review'), 22 | 'value' => PostInterface::STATUS_PENDING_REVIEW, 23 | ], 24 | [ 25 | 'label' => __('Published'), 26 | 'value' => PostInterface::STATUS_PUBLISHED, 27 | ], 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Ui/Post/Source/Tags.php: -------------------------------------------------------------------------------- 1 | tagRepository = $tagRepository; 16 | } 17 | 18 | /** 19 | * {@inheritdoc} 20 | */ 21 | public function toOptionArray() 22 | { 23 | $result = []; 24 | 25 | foreach ($this->tagRepository->getCollection() as $tag) { 26 | $result[] = [ 27 | 'label' => $tag->getName(), 28 | 'value' => $tag->getId(), 29 | ]; 30 | } 31 | 32 | return $result; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mirasvit/module-blog", 3 | "description": "Mirasvit Blog MX", 4 | "require": { 5 | "magento/framework": "100.1.*|100.2.*|101.0.*|102.0.*|103.0.*" 6 | }, 7 | "suggest": { 8 | "mirasvit/module-blog-sample-data": "Sample Data for Blog" 9 | }, 10 | "type": "magento2-module", 11 | "version": "1.0.43", 12 | "license": [ 13 | "OSL-3.0" 14 | ], 15 | "autoload": { 16 | "files": [ 17 | "registration.php" 18 | ], 19 | "psr-4": { 20 | "Mirasvit\\Blog\\": "" 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /docs/SUMMARY.md: -------------------------------------------------------------------------------- 1 | Getting Started 2 | [Installation](/setup/installation) 3 | [Quick Start](/guide/quick_start) 4 | Agent's Guide 5 | [Manage Categories](/guide/categories) 6 | [Manage Posts](/guide/posts) 7 | [Configuration](/guide/settings) 8 | [Upgrading](/setup/upgrade) 9 | [Disabling](/setup/disabling) 10 | -------------------------------------------------------------------------------- /docs/WELCOME.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | Welcome to the **Blog MX** documentation. 4 | 5 | Here you will find everything you need to set up your **Blog** service with rich content. 6 | 7 | You can even engage more and more customers in your shop activities, and promote your products with themed articles. 8 | 9 | ## Go ahead, dive in! 10 | 11 | Firstly, please, find our extension on [our store](http://mirasvit.com/). Learn [how to install extension](/setup/installation), and proceed with [Quick Start](/guide/quick_start), which will guide you to setup your Blogs service. -------------------------------------------------------------------------------- /docs/guide/categories.md: -------------------------------------------------------------------------------- 1 | # Managing Categories 2 | 3 | Categories can be defined at **Content -> Blog MX -> Categories**. They are organized in hierarchical structure, as shown below: 4 | 5 | ![Category Structure](/images/category-structure.png) 6 | 7 | As you see, field **Title** displays category names with indents, where indent size is the place in hierarchy. Root element can be only one, and it shall be **Magento 2 Blog** (name can be changed, of course), and all others are its children. 8 | 9 | Field **Status** shows, whether this category is displayed on frontend. 10 | 11 | On frontend categories are displayed in two places: 12 | * In Top Links Menu as items (direct children of root only). 13 | * In right navigation sidebar. 14 | 15 | ## Creating a New Category 16 | 17 | To create a New Category, go to **Content -> Blog MX -> Categories**, and press **Add New** button. You will see Category Edit Page, which is divided into two tabs: 18 | 19 | * **General Information** contains all base information, needed for work: 20 | * **Title** - is the name of category 21 | * **Parent Category** - defines, which category will be parent one (can be selected only one). 22 | * **Status** - defines, whether this category is eligible for blog posts and display. Possible values: 23 | * **Disabled** - default one. 24 | * **Enabled** - makes category eligible for blog posts. 25 | * **Order** - sort order, in which categories should be shown in their respective branch. 0 is the highest order. 26 | * **Search Engine Optimization** contains meta information, that can be used by web search crawlers: 27 | * **Meta Title** - title of the category (if not set, then will be equal to the respective field from previous tab). 28 | * **Meta Description** - description of this category. 29 | * **Meta Keywords** - keywords, that should be associated with this category. 30 | 31 | To save category just push **Save** button. -------------------------------------------------------------------------------- /docs/guide/quick_start.md: -------------------------------------------------------------------------------- 1 | # Quick Start 2 | 3 | Our Blog MX extension is a simple yet powerful extension, and its features work directly our-of-box. But there's more to tune-up for maximum performance. 4 | 5 | 1. Start with creation of [**Category**](/guide/categories) structure. It allows you to arrange your themes in sensical tree. 6 | 7 | 2. Write a number of [**Blog posts**](/guide/posts), and add there featured images, tags and even products to make customers shop them directly from article. 8 | 9 | 3. Tune up your blog service with flexible [**Settings**](/guide/settings), added to **Configuration** section. 10 | 11 | 4. Use your creativity to make bright and attractive Blogs. 12 | 13 | This should be a good beginning. 14 | 15 | Refer to appropriate sections of our manual to have more info. -------------------------------------------------------------------------------- /docs/images/category-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirasvit/module-blog/6de50497d090ca0fbdd3f8b59c6b0050628b96c0/docs/images/category-structure.png -------------------------------------------------------------------------------- /docs/images/posts-create-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirasvit/module-blog/6de50497d090ca0fbdd3f8b59c6b0050628b96c0/docs/images/posts-create-new.png -------------------------------------------------------------------------------- /docs/setup/disabling.md: -------------------------------------------------------------------------------- 1 | # Disabling Extension 2 | 3 | ## Temporarily Disable 4 | 5 | To temporarily disable the extension please follow these steps: 6 | 7 | 1. Login to the SSH console on your server and navigate to the root directory of the Magento 2 store. 8 | 1. Run the command `php -f bin/magento module:disable Mirasvit_Blog` to disable the extension. 9 | 1. Login to the Magento back-end and purge **ALL** store cache (if enabled). 10 | 11 | ## Extension Removing 12 | 13 | To uninstall the extension please follow these steps: 14 | 15 | 1. Login to the SSH console on your server and navigate to the root directory of the Magento 2 store. 16 | 1. Run the command `composer remove mirasvit/module-blog` to remove the extension. 17 | 1. Login to the Magento back-end and purge **ALL** store cache (if enabled). 18 | -------------------------------------------------------------------------------- /docs/setup/installation.md: -------------------------------------------------------------------------------- 1 | # Installing Blog MX extension 2 | 3 | Currently Blog MX extension can be installed only via composer. Follow these steps to install this extension on your store. 4 | 5 | 1. Backup your store's database and web directory. 6 | 1. Login to SSH console on your server and navigate to root directory of the Magento 2 store. 7 | 1. Execute the following command: ``composer require mirasvit/module-blog:*``. 8 | 1. Run command ``php -f bin/magento module:enable Mirasvit_Blog`` to enable extension. 9 | 1. Run command ``php -f bin/magento setup:upgrade`` to install the extension. 10 | 1. Run command `php -f bin/magento cache:clean` for clean the cache. 11 | 1. Deploy static view files 12 | 13 | `rm -rf pub/static/*; rm -rf var/view_preprocessed/*; php -f bin/magento setup:static-content:deploy` 14 | %%% note 15 | If you're using Magento 2.2.x, command use ```php -f bin/magento setup:static-content:deploy -f``` to deploy static contents. 16 | %%% 17 | 18 | -------------------------------------------------------------------------------- /docs/setup/upgrade.md: -------------------------------------------------------------------------------- 1 | # How to upgrade extension 2 | 3 | To upgrade the extension follow next steps: 4 | 5 | 1. Backup your store's database and web directory. 6 | 1. Login to the SSH console of your server and navigate to the root directory of the Magento 2 store. 7 | 1. Run command `composer require mirasvit/module-blog:* --update-with-dependencies` to update current extension with all dependencies. 8 | %%% note 9 | In some cases the command above is not applicable, it's not possible to update just current module, or you just need to upgrade all Mirasvit modules in a bundle. In this case command above will have no effect.

10 | Run instead `composer update mirasvit/*` command. It will update all Mirasvit modules, installed on your store.

11 | %%% 12 | 1. Run command `php -f bin/magento setup:upgrade` to install updates. 13 | 1. Run command `php -f bin/magento cache:clean` to clean the cache. 14 | 1. Deploy static view files 15 | 16 | `rm -rf pub/static/*; rm -rf var/view_preprocessed/*; 17 | php -f bin/magento setup:static-content:deploy` 18 | 19 | 20 | -------------------------------------------------------------------------------- /etc/acl.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /etc/adminhtml/menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 14 | 15 | 16 | 18 | 19 | -------------------------------------------------------------------------------- /etc/adminhtml/routes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /etc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | Blog MX 8 | Blog MX 9 | F j, Y 10 | 11 | 12 | 13 | 1 14 | 1 15 | 350 16 | 17 | 18 | 19 | disqus 20 | magento2-blog 21 | 22 | 23 | 24 | blog 25 | Blog MX 26 | Blog MX 27 | Blog MX 28 | .html 29 | .html 30 | 31 | 32 | 33 | 1 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /etc/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | Mirasvit\Blog\Model\ResourceModel\Post\Grid\Collection 20 | 21 | 22 | 23 | 24 | 25 | mst_blog_post_entity 26 | blog_post_grid_collection 27 | post_grid_collection 28 | Mirasvit\Blog\Model\ResourceModel\Post 29 | 30 | 31 | 32 | 33 | 34 | 35 | blog_post 36 | blog_category 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /etc/frontend/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | Mirasvit\Blog\Controller\Router 9 | false 10 | 50 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /etc/frontend/events.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /etc/frontend/routes.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /etc/module.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /etc/webapi.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /etc/widget.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 11 | 12 | List of Blog Posts 13 | 14 | 15 | 16 | 5 17 | 18 | 19 | 20 | 0 21 | 22 | 23 | 24 | 0 25 | 26 | 27 | 28 | 29 | 30 | List of Blog Posts 31 | 32 | 33 | 34 | 5 35 | 36 | 37 | 38 | 0 39 | 40 | 41 | 42 | 0 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /registration.php: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /view/adminhtml/layout/blog_category_edit.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /view/adminhtml/layout/blog_post_edit.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /view/adminhtml/layout/blog_post_index.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /view/adminhtml/layout/blog_post_relatedproductsgrid.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | position 10 | blog.post.tab.products 11 | getSelectedRelatedProducts 12 | links[relatedproducts] 13 | products_related 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /view/adminhtml/requirejs-config.js: -------------------------------------------------------------------------------- 1 | // required for fix issue with "max" (related products) 2 | var config = { 3 | shim: { 4 | 'Magento_Ui/js/dynamic-rows/dynamic-rows-grid': { 5 | deps: ['prototype'] 6 | }, 7 | 'Magento_Ui/js/dynamic-rows/dynamic-rows': { 8 | deps: ['prototype'] 9 | } 10 | } 11 | }; -------------------------------------------------------------------------------- /view/adminhtml/templates/post/edit/form.phtml: -------------------------------------------------------------------------------- 1 | 5 |
6 | getBlockHtml('formkey') ?> 7 | 8 | getChildHtml('message') ?> 9 | 10 | getChildHtml('sidebar') ?> 11 | 12 |
13 | getChildHtml('tabs') ?> 14 |
15 |
16 |
17 | -------------------------------------------------------------------------------- /view/adminhtml/templates/post/edit/sidebar.phtml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 9 | 10 | 11 | 12 |
13 | getChildHtml() ?> 14 |
15 | 16 | 52 | -------------------------------------------------------------------------------- /view/adminhtml/templates/post/edit/sidebar/tags.phtml: -------------------------------------------------------------------------------- 1 | 7 |
8 |
9 | 10 | Tags 11 | 12 |
13 | 14 | 19 |
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /view/adminhtml/web/css/source/_module.less: -------------------------------------------------------------------------------- 1 | @import "module/post/_form.less"; 2 | @import "module/post/_list.less"; 3 | @import "module/category/_edit.less"; -------------------------------------------------------------------------------- /view/adminhtml/web/css/source/module/category/_edit.less: -------------------------------------------------------------------------------- 1 | .blog-category-edit { 2 | .field-parent_id { 3 | .admin__field-label { 4 | span { 5 | white-space: pre; 6 | } 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /view/adminhtml/web/css/source/module/post/_list.less: -------------------------------------------------------------------------------- 1 | .blog__post-grid-actions { 2 | white-space: nowrap; 3 | 4 | span { 5 | &:after { 6 | content: ' | '; 7 | margin-left: 1rem; 8 | margin-right: 1rem; 9 | display: inline-block; 10 | color: #ddd; 11 | } 12 | 13 | &:last-child { 14 | &:after { 15 | content: ''; 16 | margin: 0; 17 | } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /view/adminhtml/web/js/post/form/area.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'uiComponent' 3 | ], function (uiComponent) { 4 | 'use strict'; 5 | 6 | return uiComponent.extend({ 7 | defaults: { 8 | template: 'Mirasvit_Blog/post/form/area' 9 | } 10 | }) 11 | }); 12 | -------------------------------------------------------------------------------- /view/adminhtml/web/js/post/form/id.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'knockout', 3 | 'jquery', 4 | 'Magento_Ui/js/form/element/abstract' 5 | ], function (ko, $, Abstract) { 6 | 'use strict'; 7 | 8 | return Abstract.extend({ 9 | defaults: { 10 | listens: { 11 | '${ $.provider }:data.name': 'updateName' 12 | }, 13 | imports: { 14 | submitUrl: '${ $.provider }:submit_url', 15 | data: '${ $.provider }:data' 16 | } 17 | }, 18 | 19 | initialize: function () { 20 | this._super(); 21 | 22 | $('#preview').on('click', function (e) { 23 | e.preventDefault(); 24 | 25 | $('#preview').addClass('loading'); 26 | 27 | $.ajax({ 28 | url: this.submitUrl, 29 | method: 'POST', 30 | dataType: 'json', 31 | data: this.data, 32 | success: function (data) { 33 | window.open(data.url, 'preview'); 34 | $('#preview').removeClass('loading'); 35 | } 36 | }); 37 | }.bind(this)) 38 | }, 39 | 40 | updateName: function (name) { 41 | $('.page-actions-inner').attr('data-title', name); 42 | $('.page-title').html(name); 43 | } 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /view/adminhtml/web/js/post/form/input-limiter.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'ko', 3 | 'jquery', 4 | 'Magento_Ui/js/form/element/textarea', 5 | 'mage/translate' 6 | ], function (ko, $, Textarea, t) { 7 | 'use strict'; 8 | 9 | return Textarea.extend({ 10 | defaults: { 11 | min: 10, 12 | max: 100000, 13 | note: t('Used {len} characters. Recommend length between {min}–{max} characters.'), 14 | 15 | listens: { 16 | value: 'updateNote' 17 | } 18 | }, 19 | 20 | initObservable: function () { 21 | this._super(); 22 | 23 | var appearTimer = setInterval(function () { 24 | var $el = $("[name=" + this.index + "]"); 25 | 26 | if ($el.length) { 27 | clearInterval(appearTimer); 28 | 29 | $el.on('keyup', function (e) { 30 | this.value($(e.target).val()); 31 | }.bind(this)); 32 | } 33 | }.bind(this), 100); 34 | 35 | return this; 36 | }, 37 | 38 | updateNote: function (value) { 39 | var len = value ? value.length : 0; 40 | 41 | if(!this.notice) { //For Magento 2.1.* (this.notice is not a function) 42 | return; 43 | } 44 | 45 | if (len > 0) { 46 | this.notice( 47 | this.note 48 | .replace('{len}', len) 49 | .replace('{min}', this.min) 50 | .replace('{max}', this.max) 51 | ); 52 | 53 | if (len < this.min || len > this.max) { 54 | this.warn(true); 55 | } else { 56 | this.warn(false); 57 | } 58 | } else { 59 | this.notice(''); 60 | 61 | } 62 | } 63 | }); 64 | }); 65 | -------------------------------------------------------------------------------- /view/adminhtml/web/js/post/form/tags.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'knockout', 3 | 'jquery', 4 | 'Magento_Ui/js/form/element/abstract', 5 | 'Mirasvit_Blog/js/lib/tokenize2' 6 | ], function (ko, $, Abstract) { 7 | 'use strict'; 8 | 9 | ko.bindingHandlers.tokenize2 = { 10 | init: function (element, valueAccessor, allBindings, model) { 11 | if (valueAccessor()) { 12 | var $el = $('#' + element.id); 13 | 14 | $el.tokenize2({ 15 | tokensAllowCustom: true 16 | }); 17 | 18 | $el.on('tokenize:tokens:add', function () { 19 | model.value($el.val()); 20 | }); 21 | $el.on('tokenize:tokens:remove', function () { 22 | model.value($el.val()); 23 | }); 24 | 25 | var $input = $('input', $el.parent()); 26 | $input.on('blur', function () { 27 | $el.trigger('tokenize:tokens:add', $input.val()); 28 | model.value($el.val()); 29 | }); 30 | 31 | var $input = $('input', $el.parent()); 32 | $input.on('blur', function () { 33 | $el.trigger('tokenize:tokens:add', $input.val()); 34 | model.value($el.val()); 35 | }) 36 | } 37 | } 38 | }; 39 | 40 | return Abstract.extend({}); 41 | }); 42 | -------------------------------------------------------------------------------- /view/adminhtml/web/template/grid/cells/actions.html: -------------------------------------------------------------------------------- 1 |
2 | 7 | 15 | 16 |
-------------------------------------------------------------------------------- /view/adminhtml/web/template/post/form/area.html: -------------------------------------------------------------------------------- 1 |
2 |
5 |
-------------------------------------------------------------------------------- /view/adminhtml/web/template/post/form/tags.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 14 | 15 |
-------------------------------------------------------------------------------- /view/frontend/templates/sidebar/tag_cloud.phtml: -------------------------------------------------------------------------------- 1 | getMaxPopularity() + 1; 9 | ?> 10 |
11 |
12 | getCollection() as $tag): ?> 13 | 14 | getName() ?> 15 | 16 | 17 |
18 |
19 | -------------------------------------------------------------------------------- /view/frontend/templates/tag/view.phtml: -------------------------------------------------------------------------------- 1 | getChildHtml('blog.post.list') ?> -------------------------------------------------------------------------------- /view/frontend/web/css/source/_module.less: -------------------------------------------------------------------------------- 1 | @import "module/_topmenu.less"; 2 | @import "module/post/_view.less"; 3 | @import "module/post/_list.less"; 4 | @import "module/post/_pinned.less"; 5 | @import "module/_sidebar.less"; 6 | @import "module/catalog/_related_posts.less"; 7 | @import "module/_copyright"; 8 | @import "module/_extends"; -------------------------------------------------------------------------------- /view/frontend/web/css/source/module/_copyright.less: -------------------------------------------------------------------------------- 1 | & when (@media-common = true) { 2 | .blog__copyright-wrapper { 3 | display: block; 4 | float: right; 5 | clear: both; 6 | margin-top: 50px; 7 | font-size: 10px !important; 8 | text-transform: none; 9 | color: #c2c2c2 !important; 10 | 11 | * { 12 | font-size: 10px !important; 13 | color: #c2c2c2 !important; 14 | 15 | } 16 | 17 | h3 { 18 | margin-top: 0; 19 | display: block; 20 | } 21 | 22 | a { 23 | text-decoration: underline !important; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /view/frontend/web/css/source/module/_extends.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirasvit/module-blog/6de50497d090ca0fbdd3f8b59c6b0050628b96c0/view/frontend/web/css/source/module/_extends.less -------------------------------------------------------------------------------- /view/frontend/web/css/source/module/_topmenu.less: -------------------------------------------------------------------------------- 1 | // 2 | // Desktop 3 | //-------------------------------------- 4 | .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) { 5 | .navigation .blog-mx.level0:last-child { 6 | float: right; 7 | } 8 | } -------------------------------------------------------------------------------- /view/frontend/web/css/source/module/catalog/_related_posts.less: -------------------------------------------------------------------------------- 1 | & when (@media-common = true) { 2 | .blog__post-catalog-related-posts { 3 | ol { 4 | list-style: none; 5 | padding: 0; 6 | 7 | li { 8 | .lib-clearfix(); 9 | margin-bottom: 3rem; 10 | 11 | .post-image { 12 | width: 30%; 13 | max-width: 10rem; 14 | float: left; 15 | padding: 0 1rem 1rem 0; 16 | border-radius: 3px; 17 | } 18 | 19 | .post-name { 20 | display: block; 21 | font-weight: 500; 22 | } 23 | } 24 | } 25 | } 26 | } 27 | 28 | // 29 | // Mobile 30 | // _____________________________________________ 31 | 32 | .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { 33 | .blog__post-catalog-related-posts { 34 | ol { 35 | li { 36 | .post-image { 37 | width: 100%; 38 | max-width: 100%; 39 | float: none; 40 | padding: 0 0 1rem 0; 41 | } 42 | } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /view/frontend/web/css/source/module/post/_pinned.less: -------------------------------------------------------------------------------- 1 | & when (@media-common = true) { 2 | .blog__post-pinned { 3 | .lib-clearfix(); 4 | margin-bottom: 3rem; 5 | position: relative; 6 | 7 | .block-title { 8 | position: absolute; 9 | top: 0; 10 | left: 0; 11 | padding: 0.5rem 1rem; 12 | background: rgba(255, 255, 255, 0.6); 13 | color: #333333; 14 | font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; 15 | font-style: normal; 16 | font-weight: 400; 17 | font-size: 1.8rem; 18 | width: 100%; 19 | } 20 | 21 | .items { 22 | .item { 23 | float: left; 24 | width: 32%; 25 | margin-right: 2%; 26 | 27 | img { 28 | width: 100%; 29 | margin-bottom: 1rem; 30 | } 31 | 32 | &:last-child { 33 | margin-right: 0; 34 | } 35 | 36 | h2 { 37 | display: block; 38 | margin-top: 0; 39 | font-weight: 500; 40 | 41 | a.title { 42 | color: #333; 43 | font-size: 1.8rem; 44 | } 45 | } 46 | } 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /view/frontend/web/css/source/module/post/_view.less: -------------------------------------------------------------------------------- 1 | & when (@media-common = true) { 2 | body.blog-post-view { 3 | .page-title { 4 | margin-bottom: 2rem; 5 | } 6 | } 7 | 8 | .blog__post-view { 9 | .lib-clearfix(); 10 | 11 | .blog__post-featured-image { 12 | float: left; 13 | padding: 0 2rem 2rem 0; 14 | } 15 | } 16 | } 17 | 18 | // 19 | // Mobile 20 | // _____________________________________________ 21 | 22 | .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { 23 | .blog__post-view { 24 | .blog__post-featured-image { 25 | padding: 0 0 2rem 0; 26 | width: 100%; 27 | max-width: 100%; 28 | } 29 | } 30 | } 31 | 32 | & when (@media-common = true) { 33 | .blog__post-view-related-posts { 34 | .lib-clearfix(); 35 | margin: 2rem 0; 36 | 37 | .block-title { 38 | font-size: 1.8rem; 39 | margin-bottom: 1rem; 40 | } 41 | 42 | ol { 43 | margin: 0 -1.5rem; 44 | list-style: none; 45 | padding: 0; 46 | 47 | li { 48 | float: left; 49 | width: 50%; 50 | padding-left: 1.5rem; 51 | box-sizing: border-box; 52 | margin-bottom: 2rem; 53 | 54 | img { 55 | max-width: 7rem; 56 | margin: 0 1rem 1rem 0; 57 | float: left; 58 | border-radius: 2px; 59 | } 60 | 61 | a.post-name { 62 | display: block; 63 | margin-top: -5px; 64 | font-weight: 500; 65 | color: #333; 66 | font-size: 1.4rem; 67 | } 68 | 69 | color: #999; 70 | font-size: 1.2rem; 71 | } 72 | } 73 | } 74 | 75 | .blog__post-view-related-products { 76 | .lib-clearfix(); 77 | margin: 2rem 0; 78 | 79 | .block-title { 80 | font-size: 1.8rem; 81 | } 82 | 83 | ol { 84 | margin: 0; 85 | list-style: none; 86 | padding: 0; 87 | } 88 | } 89 | 90 | .addthis_bar_fixed { 91 | display: none !important; 92 | } 93 | } --------------------------------------------------------------------------------