Repository: tzyganu/Magento2SampleModule
Branch: master
Commit: 1047ae6ab3b5
Files: 101
Total size: 353.3 KB
Directory structure:
gitextract_3yank7zg/
├── Api/
│ ├── AuthorRepositoryInterface.php
│ └── Data/
│ ├── AuthorInterface.php
│ └── AuthorSearchResultsInterface.php
├── Block/
│ ├── Adminhtml/
│ │ └── Author/
│ │ └── Edit/
│ │ └── Buttons/
│ │ ├── Back.php
│ │ ├── Delete.php
│ │ ├── Generic.php
│ │ ├── Reset.php
│ │ ├── Save.php
│ │ └── SaveAndContinue.php
│ ├── Author/
│ │ ├── ListAuthor/
│ │ │ ├── Rss/
│ │ │ │ └── Link.php
│ │ │ └── Rss.php
│ │ ├── ListAuthor.php
│ │ └── ViewAuthor.php
│ ├── Image.php
│ └── ImageBuilder.php
├── Controller/
│ ├── Adminhtml/
│ │ ├── Author/
│ │ │ ├── Delete.php
│ │ │ ├── Edit.php
│ │ │ ├── File/
│ │ │ │ └── Upload.php
│ │ │ ├── Image/
│ │ │ │ └── Upload.php
│ │ │ ├── Index.php
│ │ │ ├── InlineEdit.php
│ │ │ ├── MassAction.php
│ │ │ ├── MassDelete.php
│ │ │ ├── MassDisable.php
│ │ │ ├── MassEnable.php
│ │ │ ├── NewAction.php
│ │ │ ├── Save.php
│ │ │ └── Upload.php
│ │ └── Author.php
│ ├── Author/
│ │ ├── Index.php
│ │ ├── Rss.php
│ │ └── View.php
│ ├── RegistryConstants.php
│ └── Router.php
├── Helper/
│ └── Image.php
├── LICENSE
├── Model/
│ ├── Author/
│ │ ├── DataProvider.php
│ │ ├── Rss.php
│ │ └── Url.php
│ ├── Author.php
│ ├── AuthorFactory.php
│ ├── AuthorRepository.php
│ ├── FactoryInterface.php
│ ├── Image.php
│ ├── Output.php
│ ├── ResourceModel/
│ │ ├── Author/
│ │ │ ├── Collection.php
│ │ │ └── Grid/
│ │ │ ├── Collection.php
│ │ │ └── ServiceCollection.php
│ │ └── Author.php
│ ├── Routing/
│ │ ├── Entity.php
│ │ └── RoutableInterface.php
│ ├── Source/
│ │ ├── AbstractSource.php
│ │ ├── Country.php
│ │ └── Options.php
│ ├── Uploader.php
│ └── UploaderPool.php
├── Plugin/
│ └── Block/
│ └── Topmenu.php
├── README.md
├── Setup/
│ ├── InstallSchema.php
│ └── Uninstall.php
├── Test/
│ └── Unit/
│ ├── Model/
│ │ ├── Author/
│ │ │ ├── DataProviderTest.php
│ │ │ ├── RssTest.php
│ │ │ └── UrlTest.php
│ │ ├── AuthorTest.php
│ │ ├── Source/
│ │ │ └── CountryTest.php
│ │ ├── UploaderPoolTest.php
│ │ └── UploaderTest.php
│ └── Ui/
│ ├── Component/
│ │ └── Listing/
│ │ └── Column/
│ │ ├── AuthorActionsTest.php
│ │ ├── AvatarTest.php
│ │ └── Store/
│ │ └── OptionsTest.php
│ └── DataProvider/
│ └── Author/
│ └── Form/
│ └── Modifier/
│ └── AuthorDataTest.php
├── Ui/
│ ├── Component/
│ │ └── Listing/
│ │ └── Column/
│ │ ├── AuthorActions.php
│ │ ├── Avatar.php
│ │ └── Store/
│ │ └── Options.php
│ └── DataProvider/
│ └── Author/
│ └── Form/
│ └── Modifier/
│ └── AuthorData.php
├── composer.json
├── etc/
│ ├── acl.xml
│ ├── adminhtml/
│ │ ├── di.xml
│ │ ├── menu.xml
│ │ ├── routes.xml
│ │ └── system.xml
│ ├── config.xml
│ ├── di.xml
│ ├── frontend/
│ │ ├── di.xml
│ │ └── routes.xml
│ └── module.xml
├── i18l/
│ └── en_US.csv
├── registration.php
└── view/
├── adminhtml/
│ ├── layout/
│ │ ├── sample_news_author_edit.xml
│ │ └── sample_news_author_index.xml
│ ├── ui_component/
│ │ ├── sample_news_author_form.xml
│ │ └── sample_news_author_listing.xml
│ └── web/
│ └── template/
│ ├── file-preview.html
│ └── image-preview.html
└── frontend/
├── layout/
│ ├── sample_news_author_index.xml
│ └── sample_news_author_view.xml
└── templates/
├── author/
│ ├── list.phtml
│ └── view.phtml
├── image.phtml
├── image_with_borders.phtml
└── rss/
└── link.phtml
================================================
FILE CONTENTS
================================================
================================================
FILE: Api/AuthorRepositoryInterface.php
================================================
__('Back'),
'on_click' => sprintf("location.href = '%s';", $this->getBackUrl()),
'class' => 'back',
'sort_order' => 10
];
}
/**
* Get URL for back (reset) button
*
* @return string
*/
public function getBackUrl()
{
return $this->getUrl('*/*/');
}
}
================================================
FILE: Block/Adminhtml/Author/Edit/Buttons/Delete.php
================================================
getAuthorId()) {
$data = [
'label' => __('Delete Author'),
'class' => 'delete',
'on_click' => 'deleteConfirm(\'' . __(
'Are you sure you want to do this?'
) . '\', \'' . $this->getDeleteUrl() . '\')',
'sort_order' => 20,
];
}
return $data;
}
/**
* @return string
*/
public function getDeleteUrl()
{
return $this->getUrl('*/*/delete', ['author_id' => $this->getAuthorId()]);
}
}
================================================
FILE: Block/Adminhtml/Author/Edit/Buttons/Generic.php
================================================
context = $context;
$this->authorRepository = $authorRepository;
}
/**
* Return Author page ID
*
* @return int|null
*/
public function getAuthorId()
{
try {
return $this->authorRepository->getById(
$this->context->getRequest()->getParam('author_id')
)->getId();
} catch (NoSuchEntityException $e) {
return null;
}
}
/**
* Generate url by route and parameters
*
* @param string $route
* @param array $params
* @return string
*/
public function getUrl($route = '', $params = [])
{
return $this->context->getUrlBuilder()->getUrl($route, $params);
}
}
================================================
FILE: Block/Adminhtml/Author/Edit/Buttons/Reset.php
================================================
__('Reset'),
'class' => 'reset',
'on_click' => 'location.reload();',
'sort_order' => 30
];
}
}
================================================
FILE: Block/Adminhtml/Author/Edit/Buttons/Save.php
================================================
__('Save Author'),
'class' => 'save primary',
'data_attribute' => [
'mage-init' => ['button' => ['event' => 'save']],
'form-role' => 'save',
],
'sort_order' => 90,
];
}
}
================================================
FILE: Block/Adminhtml/Author/Edit/Buttons/SaveAndContinue.php
================================================
__('Save and Continue Edit'),
'class' => 'save',
'data_attribute' => [
'mage-init' => [
'button' => ['event' => 'saveAndContinueEdit'],
],
],
'sort_order' => 80,
];
}
}
================================================
FILE: Block/Author/ListAuthor/Rss/Link.php
================================================
rssModel = $rssModel;
parent::__construct($context, $data);
}
/**
* @return string
*/
public function isRssEnabled()
{
return $this->rssModel->isRssEnabled();
}
/**
* @return string
*/
public function getLabel()
{
return __('Subscribe to RSS Feed');
}
/**
* @return string
*/
public function getLink()
{
return $this->rssModel->getRssLink();
}
}
================================================
FILE: Block/Author/ListAuthor/Rss.php
================================================
rssModel = $rssModel;
$this->urlModel = $urlModel;
$this->authorCollectionFactory = $authorCollectionFactory;
$this->storeManager = $storeManager;
parent::__construct($context, $data);
}
/**
* @return int
*/
protected function getStoreId()
{
$storeId = (int)$this->getRequest()->getParam('store_id');
if ($storeId == null) {
$storeId = $this->storeManager->getStore()->getId();
}
return $storeId;
}
/**
* @return array
*/
public function getRssData()
{
$url = $this->urlModel->getListUrl();
$data = [
'title' => __('Authors'),
'description' => __('Authors'),
'link' => $url,
'charset' => 'UTF-8'
];
$collection = $this->authorCollectionFactory->create();
$collection->addStoreFilter($this->getStoreId());
$collection->addFieldToFilter('is_active', Author::STATUS_ENABLED);
$collection->addFieldToFilter('in_rss', 1);
foreach ($collection as $item) {
/** @var \Sample\News\Model\Author $item */
$description = '
';
$description = sprintf($description, $item->getAuthorUrl(), $item->getName());
$data['entries'][] = [
'title' => $item->getName(),
'link' => $item->getAuthorUrl(),
'description' => $description,
];
}
return $data;
}
/**
* Check if RSS feed allowed
*
* @return mixed
*/
public function isAllowed()
{
return $this->rssModel->isRssEnabled();
}
/**
* Get information about all feeds this Data Provider is responsible for
*
* @return array
*/
public function getFeeds()
{
$feeds = [];
$feeds[] = [
'label' => __('Authors'),
'link' => $this->rssModel->getRssLink(),
];
$result = ['group' => __('News'), 'feeds' => $feeds];
return $result;
}
/**
* @return bool
*/
public function isAuthRequired()
{
return false;
}
/**
* @return int
*/
public function getCacheLifetime()
{
$lifetime = $this->_scopeConfig->getValue(
self::CACHE_LIFETIME_CONFIG_PATH,
ScopeInterface::SCOPE_STORE
);
return $lifetime ?: null;
}
}
================================================
FILE: Block/Author/ListAuthor.php
================================================
authorCollectionFactory = $authorCollectionFactory;
$this->urlFactory = $urlFactory;
parent::__construct($context, $data);
}
/**
* @return \Sample\News\Model\ResourceModel\Author\Collection
*/
public function getAuthors()
{
if (is_null($this->authors)) {
$this->authors = $this->authorCollectionFactory->create()
->addFieldToSelect('*')
->addFieldToFilter('is_active', Author::STATUS_ENABLED)
->addStoreFilter($this->_storeManager->getStore()->getId())
->setOrder('name', 'ASC');
}
return $this->authors;
}
/**
* @return $this
*/
protected function _prepareLayout()
{
parent::_prepareLayout();
/** @var \Magento\Theme\Block\Html\Pager $pager */
$pager = $this->getLayout()->createBlock(Pager::class, 'sample_news.author.list.pager');
$pager->setCollection($this->getAuthors());
$this->setChild('pager', $pager);
$this->getAuthors()->load();
return $this;
}
/**
* @return string
*/
public function getPagerHtml()
{
return $this->getChildHtml('pager');
}
}
================================================
FILE: Block/Author/ViewAuthor.php
================================================
coreRegistry = $registry;
$this->imageBuilder = $imageBuilder;
parent::__construct($context, $data);
}
/**
* get current author
*
* @return \Sample\News\Model\Author
*/
public function getCurrentAuthor()
{
return $this->coreRegistry->registry('current_author');
}
/**
* @param $entity
* @param $imageId
* @param array $attributes
* @return \Sample\News\Block\Image
*/
public function getImage($entity, $imageId, $attributes = [])
{
return $this->imageBuilder->setEntity($entity)
->setImageId($imageId)
->setAttributes($attributes)
->create();
}
}
================================================
FILE: Block/Image.php
================================================
setTemplate($data['template']);
unset($data['template']);
}
parent::__construct($context, $data);
}
}
================================================
FILE: Block/ImageBuilder.php
================================================
helperFactory = $helperFactory;
$this->imageFactory = $imageFactory;
$this->entityCode = $entityCode;
}
/**
* @param \Magento\Framework\Model\AbstractModel $entity
* @return $this
*/
public function setEntity(AbstractModel $entity)
{
$this->entity = $entity;
return $this;
}
/**
* Set image ID
*
* @param string $imageId
* @return $this
*/
public function setImageId($imageId)
{
$this->imageId = $imageId;
return $this;
}
/**
* Set custom attributes
*
* @param array $attributes
* @return $this
*/
public function setAttributes(array $attributes)
{
if ($attributes) {
$this->attributes = $attributes;
}
return $this;
}
/**
* Retrieve image custom attributes for HTML element
*
* @return string
*/
protected function getCustomAttributes()
{
$result = [];
foreach ($this->attributes as $name => $value) {
$result[] = $name . '="' . $value . '"';
}
return !empty($result) ? implode(' ', $result) : '';
}
/**
* Calculate image ratio
*
* @param ImageHelper $helper
* @return float|int
*/
protected function getRatio(ImageHelper $helper)
{
$width = $helper->getWidth();
$height = $helper->getHeight();
if ($width && $height) {
return $height / $width;
}
return 1;
}
/**
* Create image block
*
* @return \Sample\News\Block\Image
*/
public function create()
{
/** @var ImageHelper $helper */
$helper = $this->helperFactory
->create([
'entityCode' => $this->entityCode
])
->init(
$this->entity,
$this->imageId,
$this->attributes
);
$template = $helper->getFrame()
? 'Sample_News::image.phtml'
: 'Sample_News::image_with_borders.phtml';
$imagesize = $helper->getResizedImageInfo();
$data = [
'data' => [
'template' => $template,
'image_url' => $helper->getUrl(),
'width' => $helper->getWidth(),
'height' => $helper->getHeight(),
'label' => $helper->getLabel(),
'ratio' => $this->getRatio($helper),
'custom_attributes' => $this->getCustomAttributes(),
'resized_image_width' => !empty($imagesize[0]) ? $imagesize[0] : $helper->getWidth(),
'resized_image_height' => !empty($imagesize[1]) ? $imagesize[1] : $helper->getHeight(),
],
];
return $this->imageFactory->create($data);
}
}
================================================
FILE: Controller/Adminhtml/Author/Delete.php
================================================
resultRedirectFactory->create();
$id = $this->getRequest()->getParam('author_id');
if ($id) {
try {
$this->authorRepository->deleteById($id);
$this->messageManager->addSuccessMessage(__('The author has been deleted.'));
$resultRedirect->setPath('sample_news/*/');
return $resultRedirect;
} catch (NoSuchEntityException $e) {
$this->messageManager->addErrorMessage(__('The author no longer exists.'));
return $resultRedirect->setPath('sample_news/*/');
} catch (LocalizedException $e) {
$this->messageManager->addErrorMessage($e->getMessage());
return $resultRedirect->setPath('sample_news/author/edit', ['author_id' => $id]);
} catch (\Exception $e) {
$this->messageManager->addErrorMessage(__('There was a problem deleting the author'));
return $resultRedirect->setPath('sample_news/author/edit', ['author_id' => $id]);
}
}
$this->messageManager->addErrorMessage(__('We can\'t find a author to delete.'));
$resultRedirect->setPath('sample_news/*/');
return $resultRedirect;
}
}
================================================
FILE: Controller/Adminhtml/Author/Edit.php
================================================
getRequest()->getParam('author_id');
$this->coreRegistry->register(RegistryConstants::CURRENT_AUTHOR_ID, $authorId);
return $authorId;
}
/**
* Edit or create author
*
* @return \Magento\Backend\Model\View\Result\Page
*/
public function execute()
{
$authorId = $this->_initAuthor();
/** @var \Magento\Backend\Model\View\Result\Page $resultPage */
$resultPage = $this->resultPageFactory->create();
$resultPage->setActiveMenu('Sample_News::author');
$resultPage->getConfig()->getTitle()->prepend(__('Authors'));
$resultPage->addBreadcrumb(__('News'), __('News'));
$resultPage->addBreadcrumb(__('Authors'), __('Authors'), $this->getUrl('sample_news/author'));
if ($authorId === null) {
$resultPage->addBreadcrumb(__('New Author'), __('New Author'));
$resultPage->getConfig()->getTitle()->prepend(__('New Author'));
} else {
$resultPage->addBreadcrumb(__('Edit Author'), __('Edit Author'));
$resultPage->getConfig()->getTitle()->prepend(
$this->authorRepository->getById($authorId)->getName()
);
}
return $resultPage;
}
}
================================================
FILE: Controller/Adminhtml/Author/File/Upload.php
================================================
resultPageFactory->create();
$resultPage->setActiveMenu('Sample_News::author');
$resultPage->getConfig()->getTitle()->prepend(__('Authors'));
$resultPage->addBreadcrumb(__('News'), __('News'));
$resultPage->addBreadcrumb(__('Authors'), __('Authors'));
return $resultPage;
}
}
================================================
FILE: Controller/Adminhtml/Author/InlineEdit.php
================================================
dataObjectProcessor = $dataObjectProcessor;
$this->dataObjectHelper = $dataObjectHelper;
$this->jsonFactory = $jsonFactory;
$this->authorResourceModel = $authorResourceModel;
parent::__construct($registry, $authorRepository, $resultPageFactory, $dateFilter, $context);
}
/**
* @return \Magento\Framework\Controller\ResultInterface
*/
public function execute()
{
/** @var \Magento\Framework\Controller\Result\Json $resultJson */
$resultJson = $this->jsonFactory->create();
$error = false;
$messages = [];
$postItems = $this->getRequest()->getParam('items', []);
if (!($this->getRequest()->getParam('isAjax') && count($postItems))) {
return $resultJson->setData([
'messages' => [__('Please correct the data sent.')],
'error' => true,
]);
}
foreach (array_keys($postItems) as $authorId) {
/** @var \Sample\News\Model\Author|AuthorInterface $author */
$author = $this->authorRepository->getById((int)$authorId);
try {
$authorData = $this->filterData($postItems[$authorId]);
$this->dataObjectHelper->populateWithArray($author, $authorData , AuthorInterface::class);
$this->authorResourceModel->saveAttribute($author, array_keys($authorData));
} catch (LocalizedException $e) {
$messages[] = $this->getErrorWithAuthorId($author, $e->getMessage());
$error = true;
} catch (\RuntimeException $e) {
$messages[] = $this->getErrorWithAuthorId($author, $e->getMessage());
$error = true;
} catch (\Exception $e) {
$messages[] = $this->getErrorWithAuthorId(
$author,
__('Something went wrong while saving the author.')
);
$error = true;
}
}
return $resultJson->setData([
'messages' => $messages,
'error' => $error
]);
}
/**
* Add author id to error message
*
* @param Author $author
* @param string $errorText
* @return string
*/
protected function getErrorWithAuthorId(Author $author, $errorText)
{
return '[Author ID: ' . $author->getId() . '] ' . $errorText;
}
}
================================================
FILE: Controller/Adminhtml/Author/MassAction.php
================================================
filter = $filter;
$this->collectionFactory = $collectionFactory;
$this->successMessage = $successMessage;
$this->errorMessage = $errorMessage;
parent::__construct($registry, $authorRepository, $resultPageFactory, $dateFilter, $context);
}
/**
* @param AuthorModel $author
* @return mixed
*/
protected abstract function massAction(AuthorModel $author);
/**
* execute action
*
* @return \Magento\Backend\Model\View\Result\Redirect
*/
public function execute()
{
try {
$collection = $this->filter->getCollection($this->collectionFactory->create());
$collectionSize = $collection->getSize();
foreach ($collection as $author) {
$this->massAction($author);
}
$this->messageManager->addSuccessMessage(__($this->successMessage, $collectionSize));
} catch (LocalizedException $e) {
$this->messageManager->addErrorMessage($e->getMessage());
} catch (\Exception $e) {
$this->messageManager->addExceptionMessage($e, __($this->errorMessage));
}
$redirectResult = $this->resultRedirectFactory->create();
$redirectResult->setPath('sample_news/*/index');
return $redirectResult;
}
}
================================================
FILE: Controller/Adminhtml/Author/MassDelete.php
================================================
authorRepository->delete($author);
return $this;
}
}
================================================
FILE: Controller/Adminhtml/Author/MassDisable.php
================================================
setIsActive($this->isActive);
$this->authorRepository->save($author);
return $this;
}
}
================================================
FILE: Controller/Adminhtml/Author/MassEnable.php
================================================
resultForwardFactory = $resultForwardFactory;
parent::__construct($context);
}
/**
* forward to edit
*
* @return \Magento\Backend\Model\View\Result\Forward
*/
public function execute()
{
$resultForward = $this->resultForwardFactory->create();
$resultForward->forward('edit');
return $resultForward;
}
}
================================================
FILE: Controller/Adminhtml/Author/Save.php
================================================
authorFactory = $authorFactory;
$this->dataObjectProcessor = $dataObjectProcessor;
$this->dataObjectHelper = $dataObjectHelper;
$this->uploaderPool = $uploaderPool;
parent::__construct($registry, $authorRepository, $resultPageFactory, $dateFilter, $context);
}
/**
* run the action
*
* @return \Magento\Backend\Model\View\Result\Redirect
*/
public function execute()
{
/** @var \Sample\News\Api\Data\AuthorInterface $author */
$author = null;
$data = $this->getRequest()->getPostValue();
$id = !empty($data['author_id']) ? $data['author_id'] : null;
$resultRedirect = $this->resultRedirectFactory->create();
try {
if ($id) {
$author = $this->authorRepository->getById((int)$id);
} else {
unset($data['author_id']);
$author = $this->authorFactory->create();
}
$avatar = $this->getUploader('image')->uploadFileAndGetName('avatar', $data);
$data['avatar'] = $avatar;
$resume = $this->getUploader('file')->uploadFileAndGetName('resume', $data);
$data['resume'] = $resume;
$this->dataObjectHelper->populateWithArray($author, $data, AuthorInterface::class);
$this->authorRepository->save($author);
$this->messageManager->addSuccessMessage(__('You saved the author'));
if ($this->getRequest()->getParam('back')) {
$resultRedirect->setPath('sample_news/author/edit', ['author_id' => $author->getId()]);
} else {
$resultRedirect->setPath('sample_news/author');
}
} catch (LocalizedException $e) {
$this->messageManager->addErrorMessage($e->getMessage());
if ($author != null) {
$this->storeAuthorDataToSession(
$this->dataObjectProcessor->buildOutputDataArray(
$author,
AuthorInterface::class
)
);
}
$resultRedirect->setPath('sample_news/author/edit', ['author_id' => $id]);
} catch (\Exception $e) {
$this->messageManager->addErrorMessage(__('There was a problem saving the author'));
if ($author != null) {
$this->storeAuthorDataToSession(
$this->dataObjectProcessor->buildOutputDataArray(
$author,
AuthorInterface::class
)
);
}
$resultRedirect->setPath('sample_news/author/edit', ['author_id' => $id]);
}
return $resultRedirect;
}
/**
* @param $type
* @return Uploader
* @throws \Exception
*/
protected function getUploader($type)
{
return $this->uploaderPool->getUploader($type);
}
/**
* @param $authorData
*/
protected function storeAuthorDataToSession($authorData)
{
$this->_getSession()->setSampleNewsAuthorData($authorData);
}
}
================================================
FILE: Controller/Adminhtml/Author/Upload.php
================================================
uploader = $uploader;
}
/**
* Upload file controller action
*
* @return \Magento\Framework\Controller\ResultInterface
*/
public function execute()
{
try {
$result = $this->uploader->saveFileToTmpDir($this->getFieldName());
$result['cookie'] = [
'name' => $this->_getSession()->getName(),
'value' => $this->_getSession()->getSessionId(),
'lifetime' => $this->_getSession()->getCookieLifetime(),
'path' => $this->_getSession()->getCookiePath(),
'domain' => $this->_getSession()->getCookieDomain(),
];
} catch (\Exception $e) {
$result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()];
}
return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData($result);
}
/**
* @return string
*/
protected function getFieldName()
{
return $this->_request->getParam('field');
}
}
================================================
FILE: Controller/Adminhtml/Author.php
================================================
coreRegistry = $registry;
$this->authorRepository = $authorRepository;
$this->resultPageFactory = $resultPageFactory;
$this->dateFilter = $dateFilter;
parent::__construct($context);
}
/**
* filter dates
*
* @param array $data
* @return array
*/
public function filterData($data)
{
$inputFilter = new \Zend_Filter_Input(
['dob' => $this->dateFilter],
[],
$data
);
$data = $inputFilter->getUnescaped();
if (isset($data['awards'])) {
if (is_array($data['awards'])) {
$data['awards'] = implode(',', $data['awards']);
}
}
return $data;
}
}
================================================
FILE: Controller/Author/Index.php
================================================
resultPageFactory = $resultPageFactory;
$this->scopeConfig = $scopeConfig;
}
/**
* @return \Magento\Framework\View\Result\Page
*/
public function execute()
{
$resultPage = $this->resultPageFactory->create();
$resultPage->getConfig()->getTitle()->set(
$this->scopeConfig->getValue(self::META_TITLE_CONFIG_PATH, ScopeInterface::SCOPE_STORE)
);
$resultPage->getConfig()->setDescription(
$this->scopeConfig->getValue(self::META_DESCRIPTION_CONFIG_PATH, ScopeInterface::SCOPE_STORE)
);
$resultPage->getConfig()->setKeywords(
$this->scopeConfig->getValue(self::META_KEYWORDS_CONFIG_PATH, ScopeInterface::SCOPE_STORE)
);
if ($this->scopeConfig->isSetFlag(self::BREADCRUMBS_CONFIG_PATH, ScopeInterface::SCOPE_STORE)) {
/** @var \Magento\Theme\Block\Html\Breadcrumbs $breadcrumbsBlock */
$breadcrumbsBlock = $resultPage->getLayout()->getBlock('breadcrumbs');
if ($breadcrumbsBlock) {
$breadcrumbsBlock->addCrumb(
'home',
[
'label' => __('Home'),
'link' => $this->_url->getUrl('')
]
);
$breadcrumbsBlock->addCrumb(
'authors',
[
'label' => __('Authors'),
]
);
}
}
return $resultPage;
}
}
================================================
FILE: Controller/Author/Rss.php
================================================
getRequest()->setParam('type', 'authors');
parent::execute();
}
}
================================================
FILE: Controller/Author/View.php
================================================
resultForwardFactory = $resultForwardFactory;
$this->authorRepository = $authorRepository;
$this->resultPageFactory = $resultPageFactory;
$this->coreRegistry = $coreRegistry;
$this->urlModel = $urlModel;
$this->scopeConfig = $scopeConfig;
parent::__construct($context);
}
/**
* @return \Magento\Framework\Controller\Result\Forward|\Magento\Framework\View\Result\Page
*/
public function execute()
{
try {
$authorId = (int)$this->getRequest()->getParam('id');
$author = $this->authorRepository->getById($authorId);
if (!$author->getIsActive()) {
throw new \Exception();
}
} catch (\Exception $e){
$resultForward = $this->resultForwardFactory->create();
$resultForward->forward('noroute');
return $resultForward;
}
$this->coreRegistry->register('current_author', $author);
$resultPage = $this->resultPageFactory->create();
//$title = ($author->getMetaTitle()) ?: $author->getName();
$resultPage->getConfig()->getTitle()->set($author->getName());
$resultPage->getConfig()->setDescription($author->getMetaDescription());
$resultPage->getConfig()->setKeywords($author->getMetaKeywords());
if ($this->scopeConfig->isSetFlag(self::BREADCRUMBS_CONFIG_PATH, ScopeInterface::SCOPE_STORE)) {
/** @var \Magento\Theme\Block\Html\Breadcrumbs $breadcrumbsBlock */
$breadcrumbsBlock = $resultPage->getLayout()->getBlock('breadcrumbs');
if ($breadcrumbsBlock) {
$breadcrumbsBlock->addCrumb(
'home',
[
'label' => __('Home'),
'link' => $this->_url->getUrl('')
]
);
$breadcrumbsBlock->addCrumb(
'authors',
[
'label' => __('Authors'),
'link' => $this->urlModel->getListUrl()
]
);
$breadcrumbsBlock->addCrumb(
'author-'.$author->getId(),
[
'label' => $author->getName()
]
);
}
}
return $resultPage;
}
}
================================================
FILE: Controller/RegistryConstants.php
================================================
actionFactory = $actionFactory;
$this->eventManager = $eventManager;
$this->url = $url;
$this->appState = $appState;
$this->storeManager = $storeManager;
$this->response = $response;
$this->scopeConfig = $scopeConfig;
$this->routingEntities = $routingEntities;
}
/**
* Validate and Match News Author and modify request
*
* @param \Magento\Framework\App\RequestInterface|\Magento\Framework\HTTP\PhpEnvironment\Request $request
* @return bool
*/
public function match(RequestInterface $request)
{
if (!$this->dispatched) {
$urlKey = trim($request->getPathInfo(), '/');
$origUrlKey = $urlKey;
/** @var Object $condition */
$condition = new DataObject(['url_key' => $urlKey, 'continue' => true]);
$this->eventManager->dispatch(
'sample_news_controller_router_match_before',
['router' => $this, 'condition' => $condition]
);
$urlKey = $condition->getUrlKey();
if ($condition->getRedirectUrl()) {
$this->response->setRedirect($condition->getRedirectUrl());
$request->setDispatched(true);
return $this->actionFactory->create(Redirect::class);
}
if (!$condition->getContinue()) {
return null;
}
foreach ($this->routingEntities as $entityKey => $entity) {
$match = $this->matchRoute($request, $entity, $urlKey, $origUrlKey);
if ($match === false) {
continue;
}
return $match;
}
}
return null;
}
/**
* @param RequestInterface|\Magento\Framework\HTTP\PhpEnvironment\Request $request
* @param Entity $entity
* @param $urlKey
* @param $origUrlKey
* @return bool|\Magento\Framework\App\ActionInterface|null
*/
protected function matchRoute(RequestInterface $request, Entity $entity, $urlKey, $origUrlKey)
{
$listKey = $this->scopeConfig->getValue($entity->getListKeyConfigPath(), ScopeInterface::SCOPE_STORE);
if ($listKey) {
if ($urlKey == $listKey) {
$request->setModuleName('sample_news');
$request->setControllerName($entity->getController());
$request->setActionName($entity->getListAction());
$request->setAlias(Url::REWRITE_REQUEST_PATH_ALIAS, $urlKey);
$this->dispatched = true;
return $this->actionFactory->create(Forward::class);
}
}
$prefix = $this->scopeConfig->getValue($entity->getPrefixConfigPath(), ScopeInterface::SCOPE_STORE);
if ($prefix) {
$parts = explode('/', $urlKey);
if ($parts[0] != $prefix || count($parts) != 2) {
return false;
}
$urlKey = $parts[1];
}
$configSuffix = $this->scopeConfig->getValue($entity->getSuffixConfigPath(), ScopeInterface::SCOPE_STORE);
if ($configSuffix) {
$suffix = substr($urlKey, -strlen($configSuffix) - 1);
if ($suffix != '.'.$configSuffix) {
return false;
}
$urlKey = substr($urlKey, 0, -strlen($configSuffix) - 1);
}
$instance = $entity->getFactory()->create();
$id = $instance->checkUrlKey($urlKey, $this->storeManager->getStore()->getId());
if (!$id) {
return null;
}
$request->setModuleName('sample_news');
$request->setControllerName($entity->getController());
$request->setActionName($entity->getViewAction());
$request->setParam($entity->getParam(), $id);
$request->setAlias(Url::REWRITE_REQUEST_PATH_ALIAS, $origUrlKey);
$request->setDispatched(true);
$this->dispatched = true;
return $this->actionFactory->create(Forward::class);
}
}
================================================
FILE: Helper/Image.php
================================================
imageFactory = $imageFactory;
$this->assetRepo = $assetRepo;
$this->viewConfig = $viewConfig;
$this->entityCode = $entityCode;
parent::__construct($context);
}
/**
* Reset all previous data
*
* @return $this
*/
protected function _reset()
{
$this->model = null;
$this->scheduleRotate = false;
$this->angle = null;
$this->watermark = null;
$this->watermarkPosition = null;
$this->watermarkSize = null;
$this->watermarkImageOpacity = null;
$this->entity = null;
$this->imageFile = null;
$this->attributes = [];
return $this;
}
/**
* Initialize Helper to work with Image
*
* @param \Magento\Framework\Model\AbstractModel $entity
* @param string $imageId
* @param array $attributes
* @return $this
*/
public function init($entity, $imageId, $attributes = [])
{
$this->_reset();
$this->attributes = array_merge(
$this->getConfigView()->getMediaAttributes('Sample_News', self::MEDIA_TYPE_CONFIG_NODE, $imageId),
$attributes
);
$this->setEntity($entity);
$this->setImageProperties();
$this->setWatermarkProperties();
return $this;
}
/**
* Set image properties
*
* @return $this
*/
protected function setImageProperties()
{
$this->getModel()->setDestinationSubdir($this->getType());
$this->getModel()->setWidth($this->getWidth());
$this->getModel()->setHeight($this->getHeight());
// Set 'keep frame' flag
$frame = $this->getFrame();
if (!empty($frame)) {
$this->getModel()->setKeepFrame($frame);
}
// Set 'constrain only' flag
$constrain = $this->getAttribute('constrain');
if (!empty($constrain)) {
$this->getModel()->setConstrainOnly($constrain);
}
// Set 'keep aspect ratio' flag
$aspectRatio = $this->getAttribute('aspect_ratio');
if (!empty($aspectRatio)) {
$this->getModel()->setKeepAspectRatio($aspectRatio);
}
// Set 'transparency' flag
$transparency = $this->getAttribute('transparency');
if (!empty($transparency)) {
$this->getModel()->setKeepTransparency($transparency);
}
// Set background color
$background = $this->getAttribute('background');
if (!empty($background)) {
$this->getModel()->setBackgroundColor($background);
}
return $this;
}
/**
* Set watermark properties
* @return $this
*/
protected function setWatermarkProperties()
{
// @codingStandardsIgnoreStart
//TODO: set proper watermarks paths
// @codingStandardsIgnoreEnd
$this->setWatermark(
$this->scopeConfig->getValue(
"design/watermark/{$this->getModel()->getDestinationSubdir()}_image",
ScopeInterface::SCOPE_STORE
)
);
$this->setWatermarkImageOpacity(
$this->scopeConfig->getValue(
"design/watermark/{$this->getModel()->getDestinationSubdir()}_imageOpacity",
ScopeInterface::SCOPE_STORE
)
);
$this->setWatermarkPosition(
$this->scopeConfig->getValue(
"design/watermark/{$this->getModel()->getDestinationSubdir()}_position",
ScopeInterface::SCOPE_STORE
)
);
$this->setWatermarkSize(
$this->scopeConfig->getValue(
"design/watermark/{$this->getModel()->getDestinationSubdir()}_size",
ScopeInterface::SCOPE_STORE
)
);
return $this;
}
/**
* Schedule resize of the image
* $width *or* $height can be null - in this case, lacking dimension will be calculated.
*
* @see \Sample\News\Model\Image
* @param int $width
* @param int $height
* @return $this
*/
public function resize($width, $height = null)
{
$this->getModel()->setWidth($width)->setHeight($height);
$this->scheduleResize = true;
return $this;
}
/**
* Set image quality, values in percentage from 0 to 100
*
* @param int $quality
* @return $this
*/
public function setQuality($quality)
{
$this->getModel()->setQuality($quality);
return $this;
}
/**
* Guarantee, that image picture width/height will not be distorted.
* Applicable before calling resize()
* It is true by default.
*
* @see \Sample\News\Model\Image
* @param bool $flag
* @return $this
*/
public function keepAspectRatio($flag)
{
$this->getModel()->setKeepAspectRatio($flag);
return $this;
}
/**
* Guarantee, that image will have dimensions, set in $width/$height
* Applicable before calling resize()
* Not applicable, if keepAspectRatio(false)
*
* @see \Sample\News\Model\Image
* @param bool $flag
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function keepFrame($flag)
{
$this->getModel()->setKeepFrame($flag);
return $this;
}
/**
* Guarantee, that image will not lose transparency if any.
* Applicable before calling resize()
* It is true by default.
*
* @see \Sample\News\Model\Image
* @param bool $flag
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function keepTransparency($flag)
{
$this->getModel()->setKeepTransparency($flag);
return $this;
}
/**
* Guarantee, that image picture will not be bigger, than it was.
* Applicable before calling resize()
* It is false by default
*
* @param bool $flag
* @return $this
*/
public function constrainOnly($flag)
{
$this->getModel()->setConstrainOnly($flag);
return $this;
}
/**
* Set color to fill image frame with.
* Applicable before calling resize()
* The keepTransparency(true) overrides this (if image has transparent color)
* It is white by default.
*
* @see \Sample\News\Model\Image\Image
* @param array $colorRGB
* @return $this
*/
public function backgroundColor($colorRGB)
{
// assume that 3 params were given instead of array
if (!is_array($colorRGB)) {
$colorRGB = func_get_args();
}
$this->getModel()->setBackgroundColor($colorRGB);
return $this;
}
/**
* Rotate image into specified angle
*
* @param int $angle
* @return $this
*/
public function rotate($angle)
{
$this->setAngle($angle);
$this->getModel()->setAngle($angle);
$this->scheduleRotate = true;
return $this;
}
/**
* Add watermark to image
* size param in format 100x200
*
* @param string $fileName
* @param string $position
* @param string $size
* @param int $imageOpacity
* @return $this
*/
public function watermark($fileName, $position, $size = null, $imageOpacity = null)
{
$this->setWatermark($fileName)
->setWatermarkPosition($position)
->setWatermarkSize($size)
->setWatermarkImageOpacity($imageOpacity);
return $this;
}
/**
* Set placeholder
*
* @param string $fileName
* @return void
*/
public function placeholder($fileName)
{
$this->placeholder = $fileName;
}
/**
* Get Placeholder
*
* @param null|string $placeholder
* @return string
*/
public function getPlaceholder($placeholder = null)
{
if ($placeholder) {
$placeholderFullPath = 'Sample_News::images/'.$this->entityCode.'/placeholder/' . $placeholder . '.jpg';
} else {
$placeholderFullPath = $this->placeholder
?: 'Sample_News::images/'.$this->entityCode.'/placeholder/' . $this->getModel()->getDestinationSubdir() . '.jpg';
}
return $placeholderFullPath;
}
/**
* Apply scheduled actions
*
* @return $this
* @throws \Exception
*/
protected function applyScheduledActions()
{
$this->initBaseFile();
if ($this->isScheduledActionsAllowed()) {
$model = $this->getModel();
if ($this->scheduleRotate) {
$model->rotate($this->getAngle());
}
if ($this->scheduleResize) {
$model->resize();
}
if ($this->getWatermark()) {
$model->setWatermark($this->getWatermark());
}
$model->saveFile();
}
return $this;
}
/**
* Initialize base image file
*
* @return $this
*/
protected function initBaseFile()
{
$model = $this->getModel();
$baseFile = $model->getBaseFile();
if (!$baseFile) {
if ($this->getImageFile()) {
$model->setBaseFile($this->getImageFile());
} else {
$model->setBaseFile($this->getEntity()->getData($model->getDestinationSubdir()));
}
}
return $this;
}
/**
* Check if scheduled actions is allowed
*
* @return bool
*/
protected function isScheduledActionsAllowed()
{
$model = $this->getModel();
if ($model->isBaseFilePlaceholder()
&& $model->getNewFile() === true
|| $model->isCached()
) {
return false;
}
return true;
}
/**
* Retrieve image URL
*
* @return string
*/
public function getUrl()
{
try {
$this->applyScheduledActions();
return $this->getModel()->getUrl();
} catch (\Exception $e) {
return $this->getDefaultPlaceholderUrl();
}
}
/**
* @return $this
*/
public function save()
{
$this->applyScheduledActions();
return $this;
}
/**
* Return resized image information
*
* @return array
*/
public function getResizedImageInfo()
{
$this->applyScheduledActions();
return $this->getModel()->getResizedImageInfo();
}
/**
* @param null|string $placeholder
* @return string
*/
public function getDefaultPlaceholderUrl($placeholder = null)
{
try {
$url = $this->assetRepo->getUrl($this->getPlaceholder($placeholder));
} catch (\Exception $e) {
$this->_logger->critical($e);
$url = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAnFBMVEUAAAAAAAAAAAAAAAC0tLS4uLi0tLT6+vrx8fHo6Ojj4OC+mpq7UE2wXlqzOTGtHwza2dnGaWeiJxDV0dGNJhari4uqeHi/W1edTkevSkWWNCOLEQiXEgbExMXbiorTgH+NT0a4RD+XIxTPFwm7BQHYAwHJAwDLd3aWcXDKV03JODOjNyunLCS6JQ6nCQO/q6viqKjFREOYQTrQIiHNANNfAAAAB3RSTlMCPiYZ3uvFTohbPwAAAURJREFUOMuVk9dygzAQRW3jeGUhikQvDtUl7uX//y0b4bGMCDPJAV64Z+5Ko9HkLxizEYynMCW/A9OXsETI8xkRSPeNNpDnOyZo5dChCe8pAUJ04Qd65bzYXilIaSiYrPhEisoEiS5YvOCVbdt8G1kDATGjbWV5QC7HiDNzKFCb2/J3wqKIVcuBEDImi60vxo5JEvYEQCFmB0/mt5sdHhNLF+CQHGS+3+Ok2k8HQprVAPf944E51JkuAMRZdrk7m7WDuZfncV9Awiz3uxzlcx5qAgHq5067kXkgzj7VBCSoz63YYX/stCKAQQNAKdrmJITTbERJJErojMA/Net1c/IDPBxK6cJ424WE7so0LXcuoauV585nk5fQh5AVgDvvBqgGBRaA+yFztcheAfWoytUIJbhd/3iDykcWuZhpl3eqYUz+wTdj6SFVkjRnJQAAAABJRU5ErkJggg==';
}
return $url;
}
/**
* Get current Image model
*
* @return \Sample\News\Model\Image
*/
protected function getModel()
{
if (!$this->model) {
$this->model = $this->imageFactory->create(['entityCode' => 'author']);
}
return $this->model;
}
/**
* Set Rotation Angle
*
* @param int $angle
* @return $this
*/
protected function setAngle($angle)
{
$this->angle = $angle;
return $this;
}
/**
* Get Rotation Angle
*
* @return int
*/
protected function getAngle()
{
return $this->angle;
}
/**
* Set watermark file name
*
* @param string $watermark
* @return $this
*/
protected function setWatermark($watermark)
{
$this->watermark = $watermark;
$this->getModel()->setWatermarkFile($watermark);
return $this;
}
/**
* Get watermark file name
*
* @return string
*/
protected function getWatermark()
{
return $this->watermark;
}
/**
* Set watermark position
*
* @param string $position
* @return $this
*/
protected function setWatermarkPosition($position)
{
$this->watermarkPosition = $position;
$this->getModel()->setWatermarkPosition($position);
return $this;
}
/**
* Get watermark position
*
* @return string
*/
protected function getWatermarkPosition()
{
return $this->watermarkPosition;
}
/**
* Set watermark size
* param size in format 100x200
*
* @param string $size
* @return $this
*/
public function setWatermarkSize($size)
{
$this->watermarkSize = $size;
$this->getModel()->setWatermarkSize($this->parseSize($size));
return $this;
}
/**
* Get watermark size
*
* @return string
*/
protected function getWatermarkSize()
{
return $this->watermarkSize;
}
/**
* Set watermark image opacity
*
* @param int $imageOpacity
* @return $this
*/
public function setWatermarkImageOpacity($imageOpacity)
{
$this->watermarkImageOpacity = $imageOpacity;
$this->getModel()->setWatermarkImageOpacity($imageOpacity);
return $this;
}
/**
* Get watermark image opacity
*
* @return int
*/
protected function getWatermarkImageOpacity()
{
if ($this->watermarkImageOpacity) {
return $this->watermarkImageOpacity;
}
return $this->getModel()->getWatermarkImageOpacity();
}
/**
* Set current Entity
*
* @param \Magento\Framework\Model\AbstractModel
* @return $this
*/
protected function setEntity($entity)
{
$this->entity = $entity;
return $this;
}
/**
* Get current Product
*
* @return \Magento\Framework\Model\AbstractModel
*/
protected function getEntity()
{
return $this->entity;
}
/**
* Set Image file
*
* @param string $file
* @return $this
*/
public function setImageFile($file)
{
$this->imageFile = $file;
return $this;
}
/**
* Get Image file
*
* @return string
*/
protected function getImageFile()
{
return $this->imageFile;
}
/**
* Retrieve size from string
*
* @param string $string
* @return array|bool
*/
protected function parseSize($string)
{
$size = explode('x', strtolower($string));
if (sizeof($size) == 2) {
return [
'width' => $size[0] > 0 ? $size[0] : null,
'height' => $size[1] > 0 ? $size[1] : null
];
}
return false;
}
/**
* Retrieve original image width
*
* @return int|null
*/
public function getOriginalWidth()
{
return $this->getModel()->getImageProcessor()->getOriginalWidth();
}
/**
* Retrieve original image height
*
* @return int|null
*/
public function getOriginalHeight()
{
return $this->getModel()->getImageProcessor()->getOriginalHeight();
}
/**
* Retrieve Original image size as array
* 0 - width, 1 - height
*
* @return int[]
*/
public function getOriginalSizeArray()
{
return [$this->getOriginalWidth(), $this->getOriginalHeight()];
}
/**
* Retrieve config view
*
* @return \Magento\Framework\Config\View
*/
protected function getConfigView()
{
if (!$this->configView) {
$this->configView = $this->viewConfig->getViewConfig();
}
return $this->configView;
}
/**
* Retrieve image type
*
* @return string
*/
public function getType()
{
return $this->getAttribute('type');
}
/**
* Retrieve image width
*
* @return string
*/
public function getWidth()
{
return $this->getAttribute('width');
}
/**
* Retrieve image height
*
* @return string
*/
public function getHeight()
{
return $this->getAttribute('height') ?: $this->getAttribute('width');
}
/**
* Retrieve image frame flag
*
* @return false|string
*/
public function getFrame()
{
$frame = $this->getAttribute('frame');
if (empty($frame)) {
$frame = $this->getConfigView()->getVarValue('Sample_News', 'image_white_borders');
}
return $frame;
}
/**
* Retrieve image attribute
*
* @param string $name
* @return string
*/
protected function getAttribute($name)
{
return isset($this->attributes[$name]) ? $this->attributes[$name] : null;
}
/**
* Return image label
*
* @return string
*/
public function getLabel()
{
return $this->entity->getData('name');
}
}
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2016 Marius
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: Model/Author/DataProvider.php
================================================
collection = $authorCollectionFactory->create();
$this->pool = $pool;
parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
$this->meta = $this->prepareMeta($this->meta);
}
/**
* Prepares Meta
*
* @param array $meta
* @return array
*/
public function prepareMeta(array $meta)
{
$meta = parent::getMeta();
/** @var ModifierInterface $modifier */
foreach ($this->pool->getModifiersInstances() as $modifier) {
$meta = $modifier->modifyMeta($meta);
}
return $meta;
}
/**
* Get data
*
* @return array
*/
public function getData()
{
/** @var ModifierInterface $modifier */
foreach ($this->pool->getModifiersInstances() as $modifier) {
$this->data = $modifier->modifyData($this->data);
}
return $this->data;
}
}
================================================
FILE: Model/Author/Rss.php
================================================
urlBuilder = $urlBuilder;
$this->scopeConfig = $scopeConfig;
$this->storeManager = $storeManager;
}
/**
* @return bool
*/
public function isRssEnabled()
{
return
$this->scopeConfig->getValue(self::GLOBAL_RSS_ACTIVE_CONFIG_PATH, ScopeInterface::SCOPE_STORE) &&
$this->scopeConfig->getValue(self::AUTHOR_RSS_ACTIVE_CONFIG_PATH, ScopeInterface::SCOPE_STORE);
}
/**
* @return string
*/
public function getRssLink()
{
return $this->urlBuilder->getUrl(
self::RSS_PAGE_URL,
['store' => $this->storeManager->getStore()->getId()]
);
}
}
================================================
FILE: Model/Author/Url.php
================================================
urlBuilder = $urlBuilder;
$this->scopeConfig = $scopeConfig;
}
/**
* @return string
*/
public function getListUrl()
{
$sefUrl = $this->scopeConfig->getValue(self::LIST_URL_CONFIG_PATH, ScopeInterface::SCOPE_STORE);
if ($sefUrl) {
return $this->urlBuilder->getUrl('', ['_direct' => $sefUrl]);
}
return $this->urlBuilder->getUrl('sample_news/author/index');
}
/**
* @param Author $author
* @return string
*/
public function getAuthorUrl(Author $author)
{
if ($urlKey = $author->getUrlKey()) {
$prefix = $this->scopeConfig->getValue(
self::URL_PREFIX_CONFIG_PATH,
ScopeInterface::SCOPE_STORE
);
$suffix = $this->scopeConfig->getValue(
self::URL_SUFFIX_CONFIG_PATH,
ScopeInterface::SCOPE_STORE
);
$path = (($prefix) ? $prefix . '/' : '').
$urlKey .
(($suffix) ? '.'. $suffix : '');
return $this->urlBuilder->getUrl('', ['_direct'=>$path]);
}
return $this->urlBuilder->getUrl('sample_news/author/view', ['id' => $author->getId()]);
}
}
================================================
FILE: Model/Author.php
================================================
outputProcessor = $outputProcessor;
$this->uploaderPool = $uploaderPool;
$this->filter = $filter;
$this->urlModel = $urlModel;
$this->optionProviders = $optionProviders;
parent::__construct($context, $registry, $resource, $resourceCollection, $data);
}
/**
* Initialize resource model
*
* @return void
*/
protected function _construct()
{
$this->_init(AuthorResourceModel::class);
}
/**
* Get in rss
*
* @return bool|int
*/
public function getInRss()
{
return $this->getData(AuthorInterface::IN_RSS);
}
/**
* Get type
*
* @return int
*/
public function getType()
{
return $this->getData(AuthorInterface::TYPE);
}
/**
* Get awards
*
* @return string
*/
public function getAwards()
{
return $this->getData(AuthorInterface::AWARDS);
}
/**
* Get country
*
* @return string
*/
public function getCountry()
{
return $this->getData(AuthorInterface::COUNTRY);
}
/**
* set name
*
* @param $name
* @return AuthorInterface
*/
public function setName($name)
{
return $this->setData(AuthorInterface::NAME, $name);
}
/**
* Set in rss
*
* @param $inRss
* @return AuthorInterface
*/
public function setInRss($inRss)
{
return $this->setData(AuthorInterface::IN_RSS, $inRss);
}
/**
* Set biography
*
* @param $biography
* @return AuthorInterface
*/
public function setBiography($biography)
{
return $this->setData(AuthorInterface::BIOGRAPHY, $biography);
}
/**
* Set DOB
*
* @param $dob
* @return AuthorInterface
*/
public function setDob($dob)
{
return $this->setData(AuthorInterface::DOB, $dob);
}
/**
* set type
*
* @param $type
* @return AuthorInterface
*/
public function setType($type)
{
return $this->setData(AuthorInterface::TYPE, $type);
}
/**
* set awards
*
* @param $awards
* @return AuthorInterface
*/
public function setAwards($awards)
{
return $this->setData(AuthorInterface::AWARDS, $awards);
}
/**
* Set country
*
* @param $country
* @return AuthorInterface
*/
public function setCountry($country)
{
return $this->setData(AuthorInterface::COUNTRY, $country);
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->getData(AuthorInterface::NAME);
}
/**
* Get url key
*
* @return string
*/
public function getUrlKey()
{
return $this->getData(AuthorInterface::URL_KEY);
}
/**
* Get is active
*
* @return bool|int
*/
public function getIsActive()
{
return $this->getData(AuthorInterface::IS_ACTIVE);
}
/**
* Get biography
*
* @return string
*/
public function getBiography()
{
return $this->getData(AuthorInterface::BIOGRAPHY);
}
/**
* @return mixed
*/
public function getProcessedBiography()
{
return $this->outputProcessor->filterOutput($this->getBiography());
}
/**
* Get DOB
*
* @return string
*/
public function getDob()
{
return $this->getData(AuthorInterface::DOB);
}
/**
* Get avatar
*
* @return string
*/
public function getAvatar()
{
return $this->getData(AuthorInterface::AVATAR);
}
/**
* @return bool|string
* @throws LocalizedException
*/
public function getAvatarUrl()
{
$url = false;
$avatar = $this->getAvatar();
if ($avatar) {
if (is_string($avatar)) {
$uploader = $this->uploaderPool->getUploader('image');
$url = $uploader->getBaseUrl().$uploader->getBasePath().$avatar;
} else {
throw new LocalizedException(
__('Something went wrong while getting the avatar url.')
);
}
}
return $url;
}
/**
* @return bool|string
* @throws LocalizedException
*/
public function getResumeUrl()
{
$url = false;
$resume = $this->getResume();
if ($resume) {
if (is_string($resume)) {
$uploader = $this->uploaderPool->getUploader('file');
$url = $uploader->getBaseUrl().$uploader->getBasePath().$resume;
} else {
throw new LocalizedException(
__('Something went wrong while getting the resume url.')
);
}
}
return $url;
}
/**
* Get resume
*
* @return string
*/
public function getResume()
{
return $this->getData(AuthorInterface::RESUME);
}
/**
* Get created at
*
* @return string
*/
public function getCreatedAt()
{
return $this->getData(AuthorInterface::CREATED_AT);
}
/**
* Get updated at
*
* @return string
*/
public function getUpdatedAt()
{
return $this->getData(AuthorInterface::UPDATED_AT);
}
/**
* set url key
*
* @param $urlKey
* @return AuthorInterface
*/
public function setUrlKey($urlKey)
{
return $this->setData(AuthorInterface::URL_KEY, $urlKey);
}
/**
* Set is active
*
* @param $isActive
* @return AuthorInterface
*/
public function setIsActive($isActive)
{
return $this->setData(AuthorInterface::IS_ACTIVE, $isActive);
}
/**
* set avatar
*
* @param $avatar
* @return AuthorInterface
*/
public function setAvatar($avatar)
{
return $this->setData(AuthorInterface::AVATAR, $avatar);
}
/**
* set resume
*
* @param $resume
* @return AuthorInterface
*/
public function setResume($resume)
{
return $this->setData(AuthorInterface::RESUME, $resume);
}
/**
* set created at
*
* @param $createdAt
* @return AuthorInterface
*/
public function setCreatedAt($createdAt)
{
return $this->setData(AuthorInterface::CREATED_AT, $createdAt);
}
/**
* set updated at
*
* @param $updatedAt
* @return AuthorInterface
*/
public function setUpdatedAt($updatedAt)
{
return $this->setData(AuthorInterface::UPDATED_AT, $updatedAt);
}
/**
* Check if author url key exists
* return author id if author exists
*
* @param string $urlKey
* @param int $storeId
* @return int
*/
public function checkUrlKey($urlKey, $storeId)
{
return $this->_getResource()->checkUrlKey($urlKey, $storeId);
}
/**
* Get identities
*
* @return array
*/
public function getIdentities()
{
return [self::CACHE_TAG . '_' . $this->getId()];
}
/**
* @param $storeId
* @return AuthorInterface
*/
public function setStoreId($storeId)
{
$this->setData(AuthorInterface::STORE_ID, $storeId);
return $this;
}
/**
* @return array
*/
public function getStoreId()
{
return $this->getData(AuthorInterface::STORE_ID);
}
/**
* @return string
*/
public function getMetaTitle()
{
return $this->getData(AuthorInterface::META_TITLE);
}
/**
* @param $metaTitle
* @return AuthorInterface
*/
public function setMetaTitle($metaTitle)
{
$this->setData(AuthorInterface::META_TITLE, $metaTitle);
return $this;
}
/**
* @return string
*/
public function getMetaDescription()
{
return $this->getData(AuthorInterface::META_DESCRIPTION);
}
/**
* @param $metaDescription
* @return AuthorInterface
*/
public function setMetaDescription($metaDescription)
{
$this->setData(AuthorInterface::META_DESCRIPTION, $metaDescription);
return $this;
}
/**
* @return string
*/
public function getMetaKeywords()
{
return $this->getData(AuthorInterface::META_KEYWORDS);
}
/**
* @param $metaKeywords
* @return AuthorInterface
*/
public function setMetaKeywords($metaKeywords)
{
$this->setData(AuthorInterface::META_KEYWORDS, $metaKeywords);
return $this;
}
/**
* sanitize the url key
*
* @param $string
* @return string
*/
public function formatUrlKey($string)
{
return $this->filter->translitUrl($string);
}
/**
* @return mixed
*/
public function getAuthorUrl()
{
return $this->urlModel->getAuthorUrl($this);
}
/**
* @return bool
*/
public function isActive()
{
return (bool)$this->getIsActive();
}
/**
* @param $attribute
* @return string
*/
public function getAttributeText($attribute)
{
if (!isset($this->optionProviders[$attribute])) {
return '';
}
if (!($this->optionProviders[$attribute] instanceof AbstractSource)) {
return '';
}
return $this->optionProviders[$attribute]->getOptionText($this->getData($attribute));
}
}
================================================
FILE: Model/AuthorFactory.php
================================================
_objectManager = $objectManager;
$this->_instanceName = $instanceName;
}
/**
* Create class instance with specified parameters
*
* @param array $data
* @return RoutableInterface|\Sample\News\Model\Author
*/
public function create(array $data = array())
{
return $this->_objectManager->create($this->_instanceName, $data);
}
}
================================================
FILE: Model/AuthorRepository.php
================================================
resource = $resource;
$this->storeManager = $storeManager;
$this->authorCollectionFactory = $authorCollectionFactory;
$this->searchResultsFactory = $authorSearchResultsInterfaceFactory;
$this->authorInterfaceFactory = $authorInterfaceFactory;
$this->dataObjectHelper = $dataObjectHelper;
}
/**
* Save page.
*
* @param \Sample\News\Api\Data\AuthorInterface $author
* @return \Sample\News\Api\Data\AuthorInterface
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function save(AuthorInterface $author)
{
/** @var AuthorInterface|\Magento\Framework\Model\AbstractModel $author */
if (empty($author->getStoreId())) {
$storeId = $this->storeManager->getStore()->getId();
$author->setStoreId($storeId);
}
try {
$this->resource->save($author);
} catch (\Exception $exception) {
throw new CouldNotSaveException(__(
'Could not save the author: %1',
$exception->getMessage()
));
}
return $author;
}
/**
* Retrieve Author.
*
* @param int $authorId
* @return \Sample\News\Api\Data\AuthorInterface
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getById($authorId)
{
if (!isset($this->instances[$authorId])) {
/** @var \Sample\News\Api\Data\AuthorInterface|\Magento\Framework\Model\AbstractModel $author */
$author = $this->authorInterfaceFactory->create();
$this->resource->load($author, $authorId);
if (!$author->getId()) {
throw new NoSuchEntityException(__('Requested author doesn\'t exist'));
}
$this->instances[$authorId] = $author;
}
return $this->instances[$authorId];
}
/**
* Retrieve pages matching the specified criteria.
*
* @param SearchCriteriaInterface $searchCriteria
* @return \Sample\News\Api\Data\AuthorSearchResultsInterface
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getList(SearchCriteriaInterface $searchCriteria)
{
/** @var \Sample\News\Api\Data\AuthorSearchResultsInterface $searchResults */
$searchResults = $this->searchResultsFactory->create();
$searchResults->setSearchCriteria($searchCriteria);
/** @var \Sample\News\Model\ResourceModel\Author\Collection $collection */
$collection = $this->authorCollectionFactory->create();
//Add filters from root filter group to the collection
/** @var FilterGroup $group */
foreach ($searchCriteria->getFilterGroups() as $group) {
$this->addFilterGroupToCollection($group, $collection);
}
$sortOrders = $searchCriteria->getSortOrders();
/** @var SortOrder $sortOrder */
if ($sortOrders) {
foreach ($searchCriteria->getSortOrders() as $sortOrder) {
$field = $sortOrder->getField();
$collection->addOrder(
$field,
($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC'
);
}
} else {
// set a default sorting order since this method is used constantly in many
// different blocks
$field = 'author_id';
$collection->addOrder($field, 'ASC');
}
$collection->setCurPage($searchCriteria->getCurrentPage());
$collection->setPageSize($searchCriteria->getPageSize());
/** @var \Sample\News\Api\Data\AuthorInterface[] $authors */
$authors = [];
/** @var \Sample\News\Model\Author $author */
foreach ($collection as $author) {
/** @var \Sample\News\Api\Data\AuthorInterface $authorDataObject */
$authorDataObject = $this->authorInterfaceFactory->create();
$this->dataObjectHelper->populateWithArray($authorDataObject, $author->getData(), AuthorInterface::class);
$authors[] = $authorDataObject;
}
$searchResults->setTotalCount($collection->getSize());
return $searchResults->setItems($authors);
}
/**
* Delete author.
*
* @param \Sample\News\Api\Data\AuthorInterface $author
* @return bool true on success
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function delete(AuthorInterface $author)
{
/** @var \Sample\News\Api\Data\AuthorInterface|\Magento\Framework\Model\AbstractModel $author */
$id = $author->getId();
try {
unset($this->instances[$id]);
$this->resource->delete($author);
} catch (ValidatorException $e) {
throw new CouldNotSaveException(__($e->getMessage()));
} catch (\Exception $e) {
throw new StateException(
__('Unable to remove author %1', $id)
);
}
unset($this->instances[$id]);
return true;
}
/**
* Delete author by ID.
*
* @param int $authorId
* @return bool true on success
* @throws \Magento\Framework\Exception\NoSuchEntityException
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function deleteById($authorId)
{
$author = $this->getById($authorId);
return $this->delete($author);
}
/**
* Helper function that adds a FilterGroup to the collection.
*
* @param FilterGroup $filterGroup
* @param Collection $collection
* @return $this
* @throws \Magento\Framework\Exception\InputException
*/
protected function addFilterGroupToCollection(FilterGroup $filterGroup, Collection $collection)
{
$fields = [];
$conditions = [];
foreach ($filterGroup->getFilters() as $filter) {
$condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq';
$fields[] = $filter->getField();
$conditions[] = [$condition => $filter->getValue()];
}
if ($fields) {
$collection->addFieldToFilter($fields, $conditions);
}
return $this;
}
}
================================================
FILE: Model/FactoryInterface.php
================================================
storeManager = $storeManager;
$this->uploader = $uploader;
$this->coreFileStorageDatabase = $coreFileStorageDatabase;
$this->imageFactory = $imageFactory;
$this->assetRepo = $assetRepo;
$this->viewFileSystem = $viewFileSystem;
$this->scopeConfig = $scopeConfig;
$this->entityCode = $entityCode;
parent::__construct($context, $registry, $resource, $resourceCollection, $data);
$this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
$this->mediaDirectory->create($this->uploader->getBasePath());
}
/**
* @param int $width
* @return $this
*/
public function setWidth($width)
{
$this->width = $width;
return $this;
}
/**
* @return int
*/
public function getWidth()
{
return $this->width;
}
/**
* @param int $height
* @return $this
*/
public function setHeight($height)
{
$this->height = $height;
return $this;
}
/**
* @return int
*/
public function getHeight()
{
return $this->height;
}
/**
* Set image quality, values in percentage from 0 to 100
*
* @param int $quality
* @return $this
*/
public function setQuality($quality)
{
$this->quality = $quality;
return $this;
}
/**
* Get image quality
*
* @return int
*/
public function getQuality()
{
return $this->quality;
}
/**
* @param bool $keep
* @return $this
*/
public function setKeepAspectRatio($keep)
{
$this->keepAspectRatio = (bool)$keep;
return $this;
}
/**
* @param bool $keep
* @return $this
*/
public function setKeepFrame($keep)
{
$this->keepFrame = (bool)$keep;
return $this;
}
/**
* @param bool $keep
* @return $this
*/
public function setKeepTransparency($keep)
{
$this->keepTransparency = (bool)$keep;
return $this;
}
/**
* @param bool $flag
* @return $this
*/
public function setConstrainOnly($flag)
{
$this->constrainOnly = (bool)$flag;
return $this;
}
/**
* @param int[] $rgbArray
* @return $this
*/
public function setBackgroundColor(array $rgbArray)
{
$this->backgroundColor = $rgbArray;
return $this;
}
/**
* @param string $size
* @return $this
*/
public function setSize($size)
{
// determine width and height from string
list($width, $height) = explode('x', strtolower($size), 2);
foreach (['width', 'height'] as $wh) {
${$wh} = (int)${$wh};
if (empty(${$wh})) {
${$wh} = null;
}
}
// set sizes
$this->setWidth($width)->setHeight($height);
return $this;
}
/**
* @param string|null $file
* @return bool
*/
protected function checkMemory($file = null)
{
return $this->getMemoryLimit() > $this->getMemoryUsage() + $this->getNeedMemoryForFile(
$file
)
|| $this->getMemoryLimit() == -1;
}
/**
* @return string
*/
protected function getMemoryLimit()
{
$memoryLimit = trim(strtoupper(ini_get('memory_limit')));
if (!isset($memoryLimit[0])) {
$memoryLimit = "128M";
}
if (substr($memoryLimit, -1) == 'K') {
return substr($memoryLimit, 0, -1) * 1024;
}
if (substr($memoryLimit, -1) == 'M') {
return substr($memoryLimit, 0, -1) * 1024 * 1024;
}
if (substr($memoryLimit, -1) == 'G') {
return substr($memoryLimit, 0, -1) * 1024 * 1024 * 1024;
}
return $memoryLimit;
}
/**
* @return int
*/
protected function getMemoryUsage()
{
if (function_exists('memory_get_usage')) {
return memory_get_usage();
}
return 0;
}
/**
* @param string|null $file
* @return float|int
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
protected function getNeedMemoryForFile($file = null)
{
$file = $file === null ? $this->getBaseFile() : $file;
if (!$file) {
return 0;
}
if (!$this->mediaDirectory->isExist($file)) {
return 0;
}
$imageInfo = getimagesize($this->mediaDirectory->getAbsolutePath($file));
if (!isset($imageInfo[0]) || !isset($imageInfo[1])) {
return 0;
}
if (!isset($imageInfo['channels'])) {
// if there is no info about this parameter lets set it for maximum
$imageInfo['channels'] = 4;
}
if (!isset($imageInfo['bits'])) {
// if there is no info about this parameter lets set it for maximum
$imageInfo['bits'] = 8;
}
return round(
($imageInfo[0] * $imageInfo[1] * $imageInfo['bits'] * $imageInfo['channels'] / 8 + Pow(2, 16)) * 1.65
);
}
/**
* Convert array of 3 items (decimal r, g, b) to string of their hex values
*
* @param int[] $rgbArray
* @return string
*/
protected function rgbToString($rgbArray)
{
$result = [];
foreach ($rgbArray as $value) {
if (null === $value) {
$result[] = 'null';
} else {
$result[] = sprintf('%02s', dechex($value));
}
}
return implode($result);
}
/**
* Set filenames for base file and new file
*
* @param string $file
* @return $this
* @throws \Exception
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
public function setBaseFile($file)
{
$this->isBaseFilePlaceholder = false;
if ($file && 0 !== strpos($file, '/', 0)) {
$file = '/' . $file;
}
$baseDir = $this->uploader->getBasePath();
if ($file) {
if (!$this->fileExists($baseDir . $file) || !$this->checkMemory($baseDir . $file)) {
$file = null;
}
}
if (!$file) {
$this->isBaseFilePlaceholder = true;
$this->newFile = true;
return $this;
}
$baseFile = $baseDir . $file;
if (!$file || !$this->mediaDirectory->isFile($baseFile)) {
throw new \Exception(__('We can\'t find the image file.'));
}
$this->baseFile = $baseFile;
// build new filename (most important params)
$path = [
$this->uploader->getBasePath(),
'cache',
$this->storeManager->getStore()->getId(),
$path[] = $this->getDestinationSubdir(),
];
if (!empty($this->width) || !empty($this->height)) {
$path[] = "{$this->width}x{$this->height}";
}
// add misk params as a hash
$miscParams = [
($this->keepAspectRatio ? '' : 'non') . 'proportional',
($this->keepFrame ? '' : 'no') . 'frame',
($this->keepTransparency ? '' : 'no') . 'transparency',
($this->constrainOnly ? 'do' : 'not') . 'constrainonly',
$this->rgbToString($this->backgroundColor),
'angle' . $this->angle,
'quality' . $this->quality,
];
// if has watermark add watermark params to hash
if ($this->getWatermarkFile()) {
$miscParams[] = $this->getWatermarkFile();
$miscParams[] = $this->getWatermarkImageOpacity();
$miscParams[] = $this->getWatermarkPosition();
$miscParams[] = $this->getWatermarkWidth();
$miscParams[] = $this->getWatermarkHeight();
}
$path[] = md5(implode('_', $miscParams));
// append prepared filename
$this->newFile = implode('/', $path) . $file;
// the $file contains heading slash
return $this;
}
/**
* @return string
*/
public function getBaseFile()
{
return $this->baseFile;
}
/**
* @return bool|string
*/
public function getNewFile()
{
return $this->newFile;
}
/**
* Retrieve 'true' if image is a base file placeholder
*
* @return bool
*/
public function isBaseFilePlaceholder()
{
return (bool)$this->isBaseFilePlaceholder;
}
/**
* @param MagentoImage $processor
* @return $this
*/
public function setImageProcessor($processor)
{
$this->processor = $processor;
return $this;
}
/**
* @return MagentoImage
*/
public function getImageProcessor()
{
if (!$this->processor) {
$filename = $this->getBaseFile() ? $this->mediaDirectory->getAbsolutePath($this->getBaseFile()) : null;
$this->processor = $this->imageFactory->create($filename);
}
$this->processor->keepAspectRatio($this->keepAspectRatio);
$this->processor->keepFrame($this->keepFrame);
$this->processor->keepTransparency($this->keepTransparency);
$this->processor->constrainOnly($this->constrainOnly);
$this->processor->backgroundColor($this->backgroundColor);
$this->processor->quality($this->quality);
return $this->processor;
}
/**
* @see \Magento\Framework\Image\Adapter\AbstractAdapter
* @return $this
*/
public function resize()
{
if ($this->getWidth() === null && $this->getHeight() === null) {
return $this;
}
$this->getImageProcessor()->resize($this->width, $this->height);
return $this;
}
/**
* @param int $angle
* @return $this
*/
public function rotate($angle)
{
$angle = intval($angle);
$this->getImageProcessor()->rotate($angle);
return $this;
}
/**
* Set angle for rotating
*
* This func actually affects only the cache filename.
*
* @param int $angle
* @return $this
*/
public function setAngle($angle)
{
$this->angle = $angle;
return $this;
}
/**
* Add watermark to image
* size param in format 100x200
*
* @param string $file
* @param string $position
* @param array $size ['width' => int, 'height' => int]
* @param int $width
* @param int $height
* @param int $opacity
* @return $this
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
public function setWatermark(
$file,
$position = null,
$size = null,
$width = null,
$height = null,
$opacity = null
) {
if ($this->isBaseFilePlaceholder) {
return $this;
}
if ($file) {
$this->setWatermarkFile($file);
} else {
return $this;
}
if ($position) {
$this->setWatermarkPosition($position);
}
if ($size) {
$this->setWatermarkSize($size);
}
if ($width) {
$this->setWatermarkWidth($width);
}
if ($height) {
$this->setWatermarkHeight($height);
}
if ($opacity) {
$this->setWatermarkImageOpacity($opacity);
}
$filePath = $this->getWatermarkFilePath();
if ($filePath) {
$imagePreprocessor = $this->getImageProcessor();
$imagePreprocessor->setWatermarkPosition($this->getWatermarkPosition());
$imagePreprocessor->setWatermarkImageOpacity($this->getWatermarkImageOpacity());
$imagePreprocessor->setWatermarkWidth($this->getWatermarkWidth());
$imagePreprocessor->setWatermarkHeight($this->getWatermarkHeight());
$imagePreprocessor->watermark($filePath);
}
return $this;
}
/**
* @return $this
*/
public function saveFile()
{
if ($this->isBaseFilePlaceholder && $this->newFile === true) {
return $this;
}
$filename = $this->mediaDirectory->getAbsolutePath($this->getNewFile());
$this->getImageProcessor()->save($filename);
$this->coreFileStorageDatabase->saveFile($filename);
return $this;
}
/**
* @return string
*/
public function getUrl()
{
if ($this->newFile === true) {
$url = $this->assetRepo->getUrl(
"Sample_News::images/".$this->entityCode."/placeholder/{$this->getDestinationSubdir()}.jpg"
);
} else {
$url = $this->storeManager->getStore()->getBaseUrl(
UrlInterface::URL_TYPE_MEDIA
) . $this->newFile;
}
return $url;
}
/**
* @param string $dir
* @return $this
*/
public function setDestinationSubdir($dir)
{
$this->destinationSubdir = $dir;
return $this;
}
/**
* @return string
*/
public function getDestinationSubdir()
{
return $this->destinationSubdir;
}
/**
* @return bool|void
*/
public function isCached()
{
if (is_string($this->newFile)) {
return $this->fileExists($this->newFile);
}
return false;
}
/**
* Set watermark file name
*
* @param string $file
* @return $this
*/
public function setWatermarkFile($file)
{
$this->watermarkFile = $file;
return $this;
}
/**
* Get watermark file name
*
* @return string
*/
public function getWatermarkFile()
{
return $this->watermarkFile;
}
/**
* Get relative watermark file path
* or false if file not found
*
* @return string | bool
*/
protected function getWatermarkFilePath()
{
$filePath = false;
if (!($file = $this->getWatermarkFile())) {
return $filePath;
}
$baseDir = $this->uploader->getBasePath();
$candidates = [
$baseDir . '/watermark/stores/' . $this->storeManager->getStore()->getId() . $file,
$baseDir . '/watermark/websites/' . $this->storeManager->getWebsite()->getId() . $file,
$baseDir . '/watermark/default/' . $file,
$baseDir . '/watermark/' . $file,
];
foreach ($candidates as $candidate) {
if ($this->mediaDirectory->isExist($candidate)) {
$filePath = $this->mediaDirectory->getAbsolutePath($candidate);
break;
}
}
if (!$filePath) {
$filePath = $this->viewFileSystem->getStaticFileName($file);
}
return $filePath;
}
/**
* Set watermark position
*
* @param string $position
* @return $this
*/
public function setWatermarkPosition($position)
{
$this->watermarkPosition = $position;
return $this;
}
/**
* Get watermark position
*
* @return string
*/
public function getWatermarkPosition()
{
return $this->watermarkPosition;
}
/**
* Set watermark image opacity
*
* @param int $imageOpacity
* @return $this
*/
public function setWatermarkImageOpacity($imageOpacity)
{
$this->watermarkImageOpacity = $imageOpacity;
return $this;
}
/**
* Get watermark image opacity
*
* @return int
*/
public function getWatermarkImageOpacity()
{
return $this->watermarkImageOpacity;
}
/**
* Set watermark size
*
* @param array $size
* @return $this
*/
public function setWatermarkSize($size)
{
if (is_array($size)) {
$this->setWatermarkWidth($size['width'])->setWatermarkHeight($size['height']);
}
return $this;
}
/**
* Set watermark width
*
* @param int $width
* @return $this
*/
public function setWatermarkWidth($width)
{
$this->watermarkWidth = $width;
return $this;
}
/**
* Get watermark width
*
* @return int
*/
public function getWatermarkWidth()
{
return $this->watermarkWidth;
}
/**
* Set watermark height
*
* @param int $height
* @return $this
*/
public function setWatermarkHeight($height)
{
$this->watermarkHeight = $height;
return $this;
}
/**
* Get watermark height
*
* @return string
*/
public function getWatermarkHeight()
{
return $this->watermarkHeight;
}
/**
* @return void
*/
public function clearCache()
{
$directory = $this->uploader->getBasePath() . '/cache';
$this->mediaDirectory->delete($directory);
$this->coreFileStorageDatabase->deleteFolder($this->mediaDirectory->getAbsolutePath($directory));
}
/**
* First check this file on FS
* If it doesn't exist - try to download it from DB
*
* @param string $filename
* @return bool
*/
protected function fileExists($filename)
{
if ($this->mediaDirectory->isFile($filename)) {
return true;
} else {
return $this->coreFileStorageDatabase->saveFileToFilesystem(
$this->mediaDirectory->getAbsolutePath($filename)
);
}
}
/**
* Return resized image information
*
* @return array
*/
public function getResizedImageInfo()
{
$fileInfo = null;
if ($this->newFile === true) {
$asset = $this->assetRepo->createAsset(
"Sample_News::images/".$this->entityCode."/placeholder/{$this->getDestinationSubdir()}.jpg"
);
$img = $asset->getSourceFile();
$fileInfo = getimagesize($img);
} else {
if ($this->mediaDirectory->isFile($this->mediaDirectory->getAbsolutePath($this->newFile))) {
$fileInfo = getimagesize($this->mediaDirectory->getAbsolutePath($this->newFile));
}
}
return $fileInfo;
}
}
================================================
FILE: Model/Output.php
================================================
templateProcessor = $templateProcessor;
}
/**
* @param $string
* @return string
*/
public function filterOutput($string)
{
return $this->templateProcessor->filter($string);
}
}
================================================
FILE: Model/ResourceModel/Author/Collection.php
================================================
storeManager = $storeManager;
parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
}
/**
* Define resource model
*
* @return void
*/
protected function _construct()
{
$this->_init(Author::class, AuthorResourceModel::class);
$this->_map['fields']['author_id'] = 'main_table.author_id';
$this->_map['fields']['store_id'] = 'store_table.store_id';
}
/**
* after collection load
*
* @return $this
*/
protected function _afterLoad()
{
$this->performAfterLoad('sample_news_author_store', 'author_id');
foreach ($this->getItems() as $item) {
/** @var \Sample\News\Model\Author $item */
$awards = $item->getAwards();
if ($awards && !is_array($awards)) {
$item->setAwards(explode(',', $awards));
}
}
return parent::_afterLoad();
}
public function addFieldToFilter($field, $condition = null)
{
if ($field === 'store_id') {
return $this->addStoreFilter($condition, false);
}
return parent::addFieldToFilter($field, $condition);
}
/**
* Add filter by store
*
* @param int|\Magento\Store\Model\Store $store
* @param bool $withAdmin
* @return $this
*/
public function addStoreFilter($store, $withAdmin = true)
{
if (!$this->getFlag('store_filter_added')) {
if ($store instanceof Store) {
$store = [$store->getId()];
}
if (!is_array($store)) {
$store = [$store];
}
if ($withAdmin) {
$store[] = Store::DEFAULT_STORE_ID;
}
$this->addFilter('store_id', ['in' => $store], 'public');
}
return $this;
}
/**
* Join store relation table if there is store filter
*
* @return void
* @SuppressWarnings(PHPMD.Ecg.Sql.SlowQuery)
*/
protected function _renderFiltersBefore()
{
if ($this->getFilter('store_id')) {
$this->getSelect()->join(
['store_table' => $this->getTable('sample_news_author_store')],
'main_table.author_id = store_table.author_id',
[]
)
// @codingStandardsIgnoreStart
->group('main_table.author_id');
// @codingStandardsIgnoreEnd
}
parent::_renderFiltersBefore();
}
/**
* Get SQL for get record count.
* Extra GROUP BY strip added.
*
* @return \Magento\Framework\DB\Select
*/
public function getSelectCountSql()
{
$countSelect = parent::getSelectCountSql();
$countSelect->reset(\Zend_Db_Select::GROUP);
return $countSelect;
}
/**
* @param $tableName
* @param $linkField
*/
protected function performAfterLoad($tableName, $linkField)
{
$linkedIds = $this->getColumnValues($linkField);
if (count($linkedIds)) {
$connection = $this->getConnection();
$select = $connection->select()->from(['sample_news_author_store' => $this->getTable($tableName)])
->where('sample_news_author_store.' . $linkField . ' IN (?)', $linkedIds);
// @codingStandardsIgnoreStart
$result = $connection->fetchAll($select);
// @codingStandardsIgnoreEnd
if ($result) {
$storesData = [];
foreach ($result as $storeData) {
$storesData[$storeData[$linkField]][] = $storeData['store_id'];
}
foreach ($this as $item) {
$linkedId = $item->getData($linkField);
if (!isset($storesData[$linkedId])) {
continue;
}
$storeIdKey = array_search(Store::DEFAULT_STORE_ID, $storesData[$linkedId], true);
if ($storeIdKey !== false) {
$stores = $this->storeManager->getStores(false, true);
$storeId = current($stores)->getId();
$storeCode = key($stores);
} else {
$storeId = current($storesData[$linkedId]);
$storeCode = $this->storeManager->getStore($storeId)->getCode();
}
$item->setData('store_id', $storesData[$linkedId]);
}
}
}
}
}
================================================
FILE: Model/ResourceModel/Author/Grid/Collection.php
================================================
_eventPrefix = $eventPrefix;
$this->_eventObject = $eventObject;
$this->_init($model, $resourceModel);
$this->setMainTable($mainTable);
}
/**
* @return AggregationInterface
*/
public function getAggregations()
{
return $this->aggregations;
}
/**
* @param AggregationInterface $aggregations
* @return $this
*/
public function setAggregations($aggregations)
{
$this->aggregations = $aggregations;
}
/**
* Get search criteria.
*
* @return \Magento\Framework\Api\SearchCriteriaInterface|null
*/
public function getSearchCriteria()
{
return null;
}
/**
* Set search criteria.
*
* @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function setSearchCriteria(SearchCriteriaInterface $searchCriteria = null)
{
return $this;
}
/**
* Get total count.
*
* @return int
*/
public function getTotalCount()
{
return $this->getSize();
}
/**
* Set total count.
*
* @param int $totalCount
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function setTotalCount($totalCount)
{
return $this;
}
/**
* Set items list.
*
* @param \Magento\Framework\Api\ExtensibleDataInterface[] $items
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function setItems(array $items = null)
{
return $this;
}
}
================================================
FILE: Model/ResourceModel/Author/Grid/ServiceCollection.php
================================================
authorRepository = $authorRepository;
$this->simpleDataObjectConverter = $simpleDataObjectConverter;
parent::__construct($entityFactory, $filterBuilder, $searchCriteriaBuilder, $sortOrderBuilder);
}
/**
* Load customer group collection data from service
*
* @param bool $printQuery
* @param bool $logQuery
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function loadData($printQuery = false, $logQuery = false)
{
if (!$this->isLoaded()) {
$searchCriteria = $this->getSearchCriteria();
$searchResults = $this->authorRepository->getList($searchCriteria);
$this->_totalRecords = $searchResults->getTotalCount();
/** @var AuthorInterface[] $authors */
$authors = $searchResults->getItems();
foreach ($authors as $author) {
$authorItem = new DataObject();
$authorItem->addData(
$this->simpleDataObjectConverter->toFlatArray($author, AuthorInterface::class)
);
$this->_addItem($authorItem);
}
$this->_setIsLoaded();
}
return $this;
}
}
================================================
FILE: Model/ResourceModel/Author.php
================================================
date = $date;
$this->storeManager = $storeManager;
$this->dateTime = $dateTime;
$this->eventManager = $eventManager;
parent::__construct($context);
}
/**
* Initialize resource model
*
* @return void
*/
protected function _construct()
{
$this->_init('sample_news_author', 'author_id');
}
/**
* Process author data before deleting
*
* @param \Magento\Framework\Model\AbstractModel $object
* @return $this
*/
protected function _beforeDelete(AbstractModel $object)
{
$condition = ['author_id = ?' => (int)$object->getId()];
$this->getConnection()->delete($this->getTable('sample_news_author_store'), $condition);
return parent::_beforeDelete($object);
}
/**
* before save callback
*
* @param AbstractModel|\Sample\News\Model\Author $object
* @return $this
*/
protected function _beforeSave(AbstractModel $object)
{
foreach (['dob'] as $field) {
$value = !$object->getData($field) ? null : $object->getData($field);
$object->setData($field, $this->dateTime->formatDate($value));
}
foreach (['awards'] as $field) {
if (is_array($object->getData($field))) {
$object->setData($field, implode(',', $object->getData($field)));
}
}
$object->setUpdatedAt($this->date->gmtDate());
if ($object->isObjectNew()) {
$object->setCreatedAt($this->date->gmtDate());
}
$urlKey = $object->getData('url_key');
if ($urlKey == '') {
$urlKey = $object->getName();
}
$urlKey = $object->formatUrlKey($urlKey);
$object->setUrlKey($urlKey);
$validKey = false;
while (!$validKey) {
if ($this->getIsUniqueAuthorToStores($object)) {
$validKey = true;
} else {
$urlKey = $this->generateNewUrlKey($urlKey);
$object->setData('url_key', $urlKey);
}
}
return parent::_beforeSave($object);
}
/**
* @param $urlKey
* @return string
*/
protected function generateNewUrlKey($urlKey)
{
$parts = explode('-', $urlKey);
$last = $parts[count($parts) - 1];
if (!is_numeric($last)) {
$urlKey = $urlKey.'-1';
} else {
$suffix = '-'.($last + 1);
unset($parts[count($parts) - 1]);
$urlKey = implode('-', $parts).$suffix;
}
return $urlKey;
}
/**
* Assign author to store views
*
* @param AbstractModel|\Sample\News\Model\Author $object
* @return $this
*/
protected function _afterSave(AbstractModel $object)
{
$this->saveStoreRelation($object);
return parent::_afterSave($object);
}
/**
* Perform operations after object load
*
* @param AbstractModel $object
* @return $this
*/
protected function _afterLoad(AbstractModel $object)
{
if ($object->getId()) {
$stores = $this->lookupStoreIds($object->getId());
$object->setData('store_id', $stores);
}
$awards = $object->getData('awards');
if (!is_array($awards)) {
$awards = explode(',', $awards);
$object->setData('awards', $awards);
}
return parent::_afterLoad($object);
}
/**
* Retrieve select object for load object data
*
* @param string $field
* @param mixed $value
* @param \Sample\News\Model\Author $object
* @return \Zend_Db_Select
*/
protected function _getLoadSelect($field, $value, $object)
{
$select = parent::_getLoadSelect($field, $value, $object);
if ($object->getStoreId()) {
$storeIds = [
Store::DEFAULT_STORE_ID,
(int)$object->getStoreId()
];
$select->join(
[
'sample_news_author_store' => $this->getTable('sample_news_author_store')
],
$this->getMainTable() . '.author_id = sample_news_author_store.author_id',
[]
)
->where(
'sample_news_author_store.store_id IN (?)',
$storeIds
)
->order('sample_news_author_store.store_id DESC')
->limit(1);
}
return $select;
}
/**
* Retrieve load select with filter by url_key, store and activity
*
* @param string $urlKey
* @param int|array $store
* @param int $isActive
* @return \Magento\Framework\DB\Select
*/
protected function getLoadByUrlKeySelect($urlKey, $store, $isActive = null)
{
$select = $this->getConnection()
->select()
->from(['author' => $this->getMainTable()])
->join(
['author_store' => $this->getTable('sample_news_author_store')],
'author.author_id = author_store.author_id',
[]
)
->where(
'author.url_key = ?',
$urlKey
)
->where(
'author_store.store_id IN (?)',
$store
);
if (!is_null($isActive)) {
$select->where('author.is_active = ?', $isActive);
}
return $select;
}
/**
* Check if author url_key exist
* return author id if author exists
*
* @param string $urlKey
* @param int $storeId
* @return int
*/
public function checkUrlKey($urlKey, $storeId)
{
$stores = [Store::DEFAULT_STORE_ID, $storeId];
$select = $this->getLoadByUrlKeySelect($urlKey, $stores, 1);
$select->reset(\Zend_Db_Select::COLUMNS)
->columns('author.author_id')
->order('author_store.store_id DESC')
->limit(1);
return $this->getConnection()->fetchOne($select);
}
/**
* Get store ids to which specified item is assigned
*
* @param int $authorId
* @return array
*/
public function lookupStoreIds($authorId)
{
$adapter = $this->getConnection();
$select = $adapter->select()->from(
$this->getTable('sample_news_author_store'),
'store_id'
)->where(
'author_id = ?',
(int)$authorId
);
return $adapter->fetchCol($select);
}
/**
* Set store model
*
* @param Store $store
* @return $this
*/
public function setStore(Store $store)
{
$this->store = $store;
return $this;
}
/**
* Retrieve store model
*
* @return Store
*/
public function getStore()
{
return $this->storeManager->getStore($this->store);
}
/**
* check if url key is unique
*
* @param AbstractModel|\Sample\News\Model\Author $object
* @return bool
*/
public function getIsUniqueAuthorToStores(AbstractModel $object)
{
if ($this->storeManager->hasSingleStore() || !$object->hasStores()) {
$stores = [Store::DEFAULT_STORE_ID];
} else {
$stores = (array)$object->getData('stores');
}
$select = $this->getLoadByUrlKeySelect($object->getData('url_key'), $stores);
if ($object->getId()) {
$select->where('author_store.author_id <> ?', $object->getId());
}
if ($this->getConnection()->fetchRow($select)) {
return false;
}
return true;
}
/**
* @param AuthorModel $author
* @return $this
*/
protected function saveStoreRelation(AuthorModel $author)
{
$oldStores = $this->lookupStoreIds($author->getId());
$newStores = (array)$author->getStoreId();
if (empty($newStores)) {
$newStores = (array)$author->getStoreId();
}
$table = $this->getTable('sample_news_author_store');
$insert = array_diff($newStores, $oldStores);
$delete = array_diff($oldStores, $newStores);
if ($delete) {
$where = [
'author_id = ?' => (int)$author->getId(),
'store_id IN (?)' => $delete
];
$this->getConnection()->delete($table, $where);
}
if ($insert) {
$data = [];
foreach ($insert as $storeId) {
$data[] = [
'author_id' => (int)$author->getId(),
'store_id' => (int)$storeId
];
}
$this->getConnection()->insertMultiple($table, $data);
}
return $this;
}
/**
* @param AbstractModel $object
* @param $attribute
* @return $this
* @throws \Exception
*/
public function saveAttribute(AbstractModel $object, $attribute)
{
if (is_string($attribute)) {
$attributes = [$attribute];
} else {
$attributes = $attribute;
}
if (is_array($attributes) && !empty($attributes)) {
$this->getConnection()->beginTransaction();
$data = array_intersect_key($object->getData(), array_flip($attributes));
try {
$this->beforeSaveAttribute($object, $attributes);
if ($object->getId() && !empty($data)) {
$this->getConnection()->update(
$object->getResource()->getMainTable(),
$data,
[$object->getResource()->getIdFieldName() . '= ?' => (int)$object->getId()]
);
$object->addData($data);
}
$this->afterSaveAttribute($object, $attributes);
$this->getConnection()->commit();
} catch (\Exception $e) {
$this->getConnection()->rollBack();
throw $e;
}
}
return $this;
}
/**
* @param AbstractModel $object
* @param $attribute
* @return $this
*/
protected function beforeSaveAttribute(AbstractModel $object, $attribute)
{
if ($object->getEventObject() && $object->getEventPrefix()) {
$this->eventManager->dispatch(
$object->getEventPrefix() . '_save_attribute_before',
[
$object->getEventObject() => $this,
'object' => $object,
'attribute' => $attribute
]
);
}
return $this;
}
/**
* After save object attribute
*
* @param AbstractModel $object
* @param string $attribute
* @return \Magento\Sales\Model\ResourceModel\Attribute
*/
protected function afterSaveAttribute(AbstractModel $object, $attribute)
{
if ($object->getEventObject() && $object->getEventPrefix()) {
$this->eventManager->dispatch(
$object->getEventPrefix() . '_save_attribute_after',
[
$object->getEventObject() => $this,
'object' => $object,
'attribute' => $attribute
]
);
}
return $this;
}
}
================================================
FILE: Model/Routing/Entity.php
================================================
prefixConfigPath = $prefixConfigPath;
$this->suffixConfigPath = $suffixConfigPath;
$this->listKeyConfigPath = $listKeyConfigPath;
$this->factory = $factory;
$this->controller = $controller;
$this->listAction = $listAction;
$this->viewAction = $viewAction;
$this->param = $param;
}
/**
* @return string
*/
public function getPrefixConfigPath()
{
return $this->prefixConfigPath;
}
/**
* @return string
*/
public function getSuffixConfigPath()
{
return $this->suffixConfigPath;
}
/**
* @return string
*/
public function getListKeyConfigPath()
{
return $this->listKeyConfigPath;
}
/**
* @return string
*/
public function getListAction()
{
return $this->listAction;
}
/**
* @return FactoryInterface
*/
public function getFactory()
{
return $this->factory;
}
/**
* @return mixed
*/
public function getController()
{
return $this->controller;
}
/**
* @return string
*/
public function getViewAction()
{
return $this->viewAction;
}
/**
* @return string
*/
public function getParam()
{
return $this->param;
}
}
================================================
FILE: Model/Routing/RoutableInterface.php
================================================
options = $options;
}
/**
* @return array
*/
abstract public function toOptionArray();
/**
* @param $value
* @return string
*/
public function getOptionText($value)
{
$options = $this->getOptions();
if (!is_array($value)) {
$value = explode(',', $value);
}
$texts = [];
foreach ($value as $v) {
if (isset($options[$v])) {
$texts[] = $options[$v];
}
}
return implode(', ', $texts);
}
/**
* get options as key value pair
*
* @return array
*/
public function getOptions()
{
$options = [];
foreach ($this->toOptionArray() as $values) {
$options[$values['value']] = __($values['label']);
}
return $options;
}
}
================================================
FILE: Model/Source/Country.php
================================================
countryCollectionFactory = $countryCollectionFactory;
parent::__construct($options);
}
/**
* get options as key value pair
*
* @return array
*/
public function toOptionArray()
{
if (count($this->options) == 0) {
$this->options = $this->countryCollectionFactory->create()->toOptionArray(' ');
}
return $this->options;
}
}
================================================
FILE: Model/Source/Options.php
================================================
options as $values) {
$options[] = [
'value' => $values['value'],
'label' => __($values['label'])
];
}
return $options;
}
}
================================================
FILE: Model/Uploader.php
================================================
coreFileStorageDatabase = $coreFileStorageDatabase;
$this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
$this->uploaderFactory = $uploaderFactory;
$this->storeManager = $storeManager;
$this->logger = $logger;
$this->baseTmpPath = $baseTmpPath;
$this->basePath = $basePath;
$this->allowedExtensions = $allowedExtensions;
}
/**
* Set base tmp path
*
* @param string $baseTmpPath
*
* @return void
*/
public function setBaseTmpPath($baseTmpPath)
{
$this->baseTmpPath = $baseTmpPath;
}
/**
* Set base path
*
* @param string $basePath
*
* @return void
*/
public function setBasePath($basePath)
{
$this->basePath = $basePath;
}
/**
* Set allowed extensions
*
* @param string[] $allowedExtensions
*
* @return void
*/
public function setAllowedExtensions($allowedExtensions)
{
$this->allowedExtensions = $allowedExtensions;
}
/**
* Retrieve base tmp path
*
* @return string
*/
public function getBaseTmpPath()
{
return $this->baseTmpPath;
}
/**
* Retrieve base path
*
* @return string
*/
public function getBasePath()
{
return $this->basePath;
}
/**
* Retrieve base path
*
* @return string[]
*/
public function getAllowedExtensions()
{
return $this->allowedExtensions;
}
/**
* Retrieve path
*
* @param string $path
* @param string $name
*
* @return string
*/
public function getFilePath($path, $name)
{
return rtrim($path, '/') . '/' . ltrim($name, '/');
}
/**
* Checking file for moving and move it
*
* @param string $name
*
* @return string
*
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function moveFileFromTmp($name)
{
$baseTmpPath = $this->getBaseTmpPath();
$basePath = $this->getBasePath();
$baseFilePath = $this->getFilePath($basePath, $name);
$baseTmpFilePath = $this->getFilePath($baseTmpPath, $name);
try {
$this->coreFileStorageDatabase->copyFile(
$baseTmpFilePath,
$baseFilePath
);
$this->mediaDirectory->renameFile(
$baseTmpFilePath,
$baseFilePath
);
} catch (\Exception $e) {
throw new LocalizedException(
__('Something went wrong while saving the file(s).')
);
}
return $name;
}
public function getBaseUrl()
{
return $this->storeManager
->getStore()
->getBaseUrl(
UrlInterface::URL_TYPE_MEDIA
);
}
/**
* Checking file for save and save it to tmp dir
*
* @param string $fileId
*
* @return string[]
*
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function saveFileToTmpDir($fileId)
{
$baseTmpPath = $this->getBaseTmpPath();
$uploader = $this->uploaderFactory->create(['fileId' => $fileId]);
$uploader->setAllowedExtensions($this->getAllowedExtensions());
$uploader->setAllowRenameFiles(true);
$uploader->setFilesDispersion(true);
$result = $uploader->save($this->mediaDirectory->getAbsolutePath($baseTmpPath));
if (!$result) {
throw new LocalizedException(
__('File can not be saved to the destination folder.')
);
}
/**
* Workaround for prototype 1.7 methods "isJSON", "evalJSON" on Windows OS
*/
$result['tmp_name'] = str_replace('\\', '/', $result['tmp_name']);
$result['path'] = str_replace('\\', '/', $result['path']);
$result['url'] = $this->getBaseUrl() . $this->getFilePath($baseTmpPath, $result['file']);
if (isset($result['file'])) {
try {
$relativePath = rtrim($baseTmpPath, '/') . '/' . ltrim($result['file'], '/');
$this->coreFileStorageDatabase->saveFile($relativePath);
} catch (\Exception $e) {
$this->logger->critical($e);
throw new LocalizedException(
__('Something went wrong while saving the file(s).')
);
}
}
return $result;
}
/**
* @param $input
* @param $data
* @return string
*/
public function uploadFileAndGetName($input, $data)
{
if (!isset($data[$input])) {
return '';
}
if (is_array($data[$input]) && !empty($data[$input]['delete'])) {
return '';
}
if (isset($data[$input][0]['name']) && isset($data[$input][0]['tmp_name'])) {
try {
$result = $this->moveFileFromTmp($data[$input][0]['file']);
return $result;
} catch (\Exception $e) {
return '';
}
} elseif (isset($data[$input][0]['name'])) {
return $data[$input][0]['name'];
}
return '';
}
}
================================================
FILE: Model/UploaderPool.php
================================================
objectManager = $objectManager;
$this->uploaders = $uploaders;
}
/**
* @param $type
* @return Uploader
* @throws \Exception
*/
public function getUploader($type)
{
if (!isset($this->uploaders[$type])) {
throw new \Exception("Uploader not found for type: ".$type);
}
if (!is_object($this->uploaders[$type])) {
$this->uploaders[$type] = $this->objectManager->create($this->uploaders[$type]);
}
$uploader = $this->uploaders[$type];
if (!($uploader instanceof Uploader)) {
throw new \Exception("Uploader for type {$type} not instance of ". Uploader::class);
}
return $uploader;
}
}
================================================
FILE: Plugin/Block/Topmenu.php
================================================
url = $url;
$this->request = $request;
}
/**
* @param TopmenuBlock $subject
* @param string $outermostClass
* @param string $childrenWrapClass
* @param int $limit
* @SuppressWarnings("PMD.UnusedFormalParameter")
*/
// @codingStandardsIgnoreStart
public function beforeGetHtml(
TopmenuBlock $subject,
$outermostClass = '',
$childrenWrapClass = '',
$limit = 0
) {
// @codingStandardsIgnoreEnd
$node = new Node(
$this->getNodeAsArray(),
'id',
$subject->getMenu()->getTree(),
$subject->getMenu()
);
$subject->getMenu()->addChild($node);
}
/**
* @return array
*/
protected function getNodeAsArray()
{
return [
'name' => __('Authors'),
'id' => 'authors-node',
'url' => $this->url->getListUrl(),
'has_active' => false,
'is_active' => in_array($this->request->getFullActionName(), $this->getActiveHandles())
];
}
/**
* @return array
*/
protected function getActiveHandles()
{
return [
'sample_news_author_index',
'sample_news_author_view'
];
}
}
================================================
FILE: README.md
================================================
Magento 2.0 Sample Module
====================
Last tested on Magento2 version 2.1

What I got so far:
----------
- One custom entity Author. flat and related to store views
- Backend section for the entity mentioned above
- Frontend list and view for the entity mentioned above
- List on Author view page on frontend
- Rss feeds for author list.
- Breadcrumbs support for list and view pages.
The other types of entities and features listed in **the purpose** will follow.
Don't put many hopes in this. Based on the comments on the magento 2 repo the grid system will be changed...A LOT.
The purpose
----------
....of this repository is to hold a sample CRUD module for Magento 2.0.
This module should contain the following:
* 4 Entities.
* 1 Flat - with a store selector. Similar to CMS pages
* 1 Flat but behaving as a tree - with a store selector. Similar to categories but non EAV
* 1 EAV - similar to products
* 1 EAV but behaving as tree - Similar to categories.
* Backend files for managing the entities mentioned above
* Frontend files for list and view each of the entities mentioned above
* RSS feeds for each entity mentioned above
* SOAP & REST API files for the entities mentioned above
* URL rewrites filed for frontend for the entities above
* Files needed for a many to many relation between the entities above and products
* Files needed for a many to many relation between the entities above and categories
* Files needed for a many to many relation between the entities above (among themselves)
* Each entity must support different attribute types:
* Text
* Textarea (with and without WYSIWYG editor)
* Date
* Yes/No
* Dropdown (with different source models)
* Multi-select (with different source models)
* File
* Image
* Decimal
* Integer (signed and unsigned)
* Color
* Each entity should have fronend links to the list page in one of the menu/link areas provided by the default theme
* Each entity must have SEO attributes (meta-title, meta-description, meta-keywords)
* Would be nice to have unit tests for every class in the code - but that's low priority.
* Each entity type must have widgets for frontend (link, short view).
* Each entity must support customer comments.
* Each EAV entity must have a section for managing attributes (similar to product attributes).
After this is complete (or almost) it will become the base source for the Ultimate Module Creator 2.0 which will be a version for Magento 2.0 of the [Ultimate Module Creator for Magento 1.7](https://github.com/tzyganu/UMC1.9).
Any other ideas and pieces of code are welcomed even encouraged.
Install
-----
Manually:
To install this module copy the code from this repo to `app/code` folder of your Magento 2 instance,
If you do this after installing Magento 2 you need to run `php bin/magento setup:upgrade`
Via composer
- composer config repositories.sample-module-news git git@github.com:tzyganu/Magento2SampleModule.git
- sudo composer require sample/module-news:dev-master
- php bin/magento setup:upgrade
Uninstall
--------
If you installed it manually:
- remove the folder `app/code/Sample/News`
- drop the tables `sample_news_author_store` and `sample_news_author` (in this order)
- remove the config settings. `DELETE FROM core_config_data WHERE path LIKE 'sample_news/%'`
- remove the module `Sample_News` from `app/etc/config.php`
- remove the module `Sample_News` from table `setup_module`: `DELETE FROM setup_module WHERE module='Sample_News'`
If you installed it via composer:
- run this in console `bin/magento module:uninstall -r Sample_News`. You might have some problems while uninstalling. See more [details here](http://magento.stackexchange.com/q/123544/146):
================================================
FILE: Setup/InstallSchema.php
================================================
startSetup();
if (!$installer->tableExists('sample_news_author')) {
$table = $installer->getConnection()
->newTable($installer->getTable('sample_news_author'));
$table->addColumn(
'author_id',
Table::TYPE_INTEGER,
null,
[
'identity' => true,
'unsigned' => true,
'nullable' => false,
'primary' => true
],
'Author ID'
)
->addColumn(
'name',
Table::TYPE_TEXT,
255,
['nullable' => false,],
'Author Name'
)
->addColumn(
'url_key',
Table::TYPE_TEXT,
255,
['nullable' => false,],
'Author Url Key'
)
->addColumn(
'biography',
Table::TYPE_TEXT,
'2M',
[],
'Author Biography'
)
->addColumn(
'dob',
Table::TYPE_DATE,
null,
[],
'Author Birth date'
)
->addColumn(
'awards',
Table::TYPE_TEXT,
'2M',
[],
'Author Awards'
)
->addColumn(
'type',
Table::TYPE_INTEGER,
null,
[],
'Author Type'
)
->addColumn(
'avatar',
Table::TYPE_TEXT,
255,
[],
'Author Avatar'
)
->addColumn(
'resume',
Table::TYPE_TEXT,
255,
[],
'Author Resume'
)
->addColumn(
'country',
Table::TYPE_TEXT,
2,
[],
'Author Country'
)
->addColumn(
'meta_title',
Table::TYPE_TEXT,
255,
[],
'Author Meta Title'
)
->addColumn(
'meta_description',
Table::TYPE_TEXT,
'2M',
[],
'Author Meta Description'
)
->addColumn(
'meta_keywords',
Table::TYPE_TEXT,
'2M',
[],
'Author Meta Keywords'
)
->addColumn(
'is_active',
Table::TYPE_INTEGER,
null,
[
'nullable' => false,
'default' => '1',
],
'Is Author Active'
)
->addColumn(
'in_rss',
Table::TYPE_INTEGER,
null,
[
'nullable' => false,
'default' => '1',
],
'Show in rss'
)
->addColumn(
'updated_at',
Table::TYPE_TIMESTAMP,
null,
[],
'Update at'
)
->addColumn(
'created_at',
Table::TYPE_TIMESTAMP,
null,
[],
'Creation Time'
)
->setComment('News authors');
$installer->getConnection()->createTable($table);
$installer->getConnection()->addIndex(
$installer->getTable('sample_news_author'),
$setup->getIdxName(
$installer->getTable('sample_news_author'),
['name','photo'],
AdapterInterface::INDEX_TYPE_FULLTEXT
),
[
'name',
'biography',
'url_key',
'resume',
'country',
'meta_title',
'meta_keywords',
'meta_description'
],
AdapterInterface::INDEX_TYPE_FULLTEXT
);
}
//Create Authors to Store table
if (!$installer->tableExists('sample_news_author_store')) {
$table = $installer->getConnection()
->newTable($installer->getTable('sample_news_author_store'));
$table->addColumn(
'author_id',
Table::TYPE_INTEGER,
null,
[
'unsigned' => true,
'nullable' => false,
'primary' => true,
],
'Author ID'
)
->addColumn(
'store_id',
Table::TYPE_SMALLINT,
null,
[
'unsigned' => true,
'nullable' => false,
'primary' => true,
],
'Store ID'
)
->addIndex(
$installer->getIdxName('sample_news_author_store', ['store_id']),
['store_id']
)
->addForeignKey(
$installer->getFkName('sample_news_author_store', 'author_id', 'sample_news_author', 'author_id'),
'author_id',
$installer->getTable('sample_news_author'),
'author_id',
Table::ACTION_CASCADE
)
->addForeignKey(
$installer->getFkName('sample_news_author_store', 'store_id', 'store', 'store_id'),
'store_id',
$installer->getTable('store'),
'store_id',
Table::ACTION_CASCADE
)
->setComment('Author To Store Link Table');
$installer->getConnection()->createTable($table);
}
}
}
================================================
FILE: Setup/Uninstall.php
================================================
collectionFactory = $collectionFactory;
$this->configResource = $configResource;
}
/**
* {@inheritdoc}
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @SuppressWarnings(PHPMD.Generic.CodeAnalysis.UnusedFunctionParameter)
*/
// @codingStandardsIgnoreStart
public function uninstall(SchemaSetupInterface $setup, ModuleContextInterface $context)
// @codingStandardsIgnoreEnd
{
//remove tables
if ($setup->tableExists('sample_news_author_store')) {
$setup->getConnection()->dropTable('sample_news_author_store');
}
if ($setup->tableExists('sample_news_author')) {
$setup->getConnection()->dropTable('sample_news_author');
}
//remove config settings if any
$collection = $this->collectionFactory->create()
->addPathFilter('sample_news');
foreach ($collection as $config) {
$this->deleteConfig($config);
}
}
/**
* @param AbstractModel $config
* @throws \Exception
*/
protected function deleteConfig(AbstractModel $config)
{
$this->configResource->delete($config);
}
}
================================================
FILE: Test/Unit/Model/Author/DataProviderTest.php
================================================
getMockBuilder(PoolInterface::class)
->disableOriginalConstructor()
->getMock();
/** @var \PHPUnit_Framework_MockObject_MockObject|ModifierInterface $modifierMock */
$modifierMock = $this->getMockBuilder(ModifierInterface::class)
->disableOriginalConstructor()
->getMock();
$modifierMock->method('modifyMeta')->willReturn($this->getDummyMeta());
$modifierMock->method('modifyData')->willReturn($this->getDummyData());
$poolMock->method('getModifiersInstances')->willReturn([$modifierMock]);
/** @var ModifierInterface|CollectionFactory $collectionFactoryMock */
$collectionFactoryMock = $this->getMockBuilder(CollectionFactory::class)
->disableOriginalConstructor()
->getMock();
$this->dataProvider = new DataProvider(
'dummy',
'dummy_id',
'dummy_id',
$collectionFactoryMock,
$poolMock,
[],
[]
);
}
/**
* @return array
*/
protected function getDummyMeta()
{
return ['dummy_meta_key'=>'dummy_meta_value'];
}
/**
* @return array
*/
protected function getDummyData()
{
return ['dummy_data_key'=>'dummy_data_value'];
}
/**
* tests DataProvider::prepareMeta()
*/
public function testPrepareMeta()
{
$this->assertEquals($this->getDummyMeta(), $this->dataProvider->prepareMeta([]));
}
/**
* tests DataProvider::getData()
*/
public function testGetData()
{
$this->assertEquals($this->getDummyData(), $this->dataProvider->getData());
}
}
================================================
FILE: Test/Unit/Model/Author/RssTest.php
================================================
urlMockBuilder = $this->getMockBuilder(UrlInterface::class)
->disableOriginalConstructor()
->getMock();
$this->urlMockBuilder
->expects($this->any())
->method('getUrl')
->willReturnMap(
[
[
'sample_news/author/rss',
[
'store' => self::STORE_ID
],
'some/url/here'
]
]
);
$this->scopeConfigMock = $this->getMockBuilder(ScopeConfigInterface::class)
->disableOriginalConstructor()
->getMock();
$this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class)
->disableOriginalConstructor()
->getMock();
$storeMock = $this->getMockBuilder(StoreInterface::class)
->disableOriginalConstructor()
->getMock();
$storeMock->expects($this->any())->method('getId')->willReturn(self::STORE_ID);
$this->storeManagerMock->expects($this->any())->method('getStore')->willReturn($storeMock);
$this->rss = new Rss(
$this->urlMockBuilder,
$this->scopeConfigMock,
$this->storeManagerMock
);
}
/**
* @test \Sample\News\Model\Author\Rss::isRssEnabled()
*
* with global rss setting disabled
* and author rss disabled
*/
public function testIsRssEnabledGlobalFalseAuthorFalse()
{
$this->scopeConfigMock->expects($this->any())
->method('getValue')
->willReturnMap(
[
[
'rss/config/active',
ScopeInterface::SCOPE_STORE,
null,
false
],
[
'sample_news/author/rss',
ScopeInterface::SCOPE_STORE,
null,
false
],
]
);
$this->assertFalse($this->rss->isRssEnabled());
}
/**
* @test \Sample\News\Model\Author\Rss::isRssEnabled()
*
* with global rss setting enabled
* and author rss disabled
*/
public function testIsRssEnabledGlobalTrueAuthorFalse()
{
$this->scopeConfigMock->expects($this->any())
->method('getValue')
->willReturnMap(
[
[
'rss/config/active',
ScopeInterface::SCOPE_STORE,
null,
true
],
[
'sample_news/author/rss',
ScopeInterface::SCOPE_STORE,
null,
false
],
]
);
$this->assertFalse($this->rss->isRssEnabled());
}
/**
* @test \Sample\News\Model\Author\Rss::isRssEnabled()
*
* with global rss setting disabled
* and author rss enabled
*/
public function testIsRssEnabledGlobalFalseAuthorTrue()
{
$this->scopeConfigMock->expects($this->any())
->method('getValue')
->willReturnMap(
[
[
'rss/config/active',
ScopeInterface::SCOPE_STORE,
null,
false
],
[
'sample_news/author/rss',
ScopeInterface::SCOPE_STORE,
null,
true
],
]
);
$this->assertFalse($this->rss->isRssEnabled());
}
/**
* @test \Sample\News\Model\Author\Rss::isRssEnabled()
*
* with global rss setting enabled
* and author rss enabled
*/
public function testIsRssEnabledGlobalTrueAuthorTrue()
{
$this->scopeConfigMock->expects($this->any())
->method('getValue')
->willReturnMap(
[
[
'rss/config/active',
ScopeInterface::SCOPE_STORE,
null,
true
],
[
'sample_news/author/rss',
ScopeInterface::SCOPE_STORE,
null,
true
],
]
);
$this->assertTrue($this->rss->isRssEnabled());
}
/**
* @test \Sample\News\Model\Author\Rss::isRssEnabled()
*/
public function testGetRssLink()
{
$this->assertEquals('some/url/here', $this->rss->getRssLink());
}
}
================================================
FILE: Test/Unit/Model/Author/UrlTest.php
================================================
urlMockBuilder = $this->getMockBuilder(UrlInterface::class)
->disableOriginalConstructor()
->getMock();
$this->urlMockBuilder->expects($this->any())
->method('getUrl')
->willReturnMap(
[
[
'',
[
'_direct' => self::LIST_URL_KEY
],
'http://example.com/'.self::LIST_URL_KEY,
],
[
'sample_news/author/index',
null,
'http://example.com/sample_news/author/index'
],
[
'sample_news/author/view',
['id' => 1],
'http://example.com/sample_news/author/view/id/1'
],
[
'',
[
'_direct' => self::ITEM_URL_KEY
],
'http://example.com/'.self::ITEM_URL_KEY,
],
[
'',
[
'_direct' => 'author/'.self::ITEM_URL_KEY
],
'http://example.com/author/'.self::ITEM_URL_KEY,
],
[
'',
[
'_direct' => 'author/'.self::ITEM_URL_KEY.'.html'
],
'http://example.com/author/'.self::ITEM_URL_KEY.'.html',
],
[
'',
[
'_direct' => self::ITEM_URL_KEY.'.html'
],
'http://example.com/'.self::ITEM_URL_KEY.'.html',
],
]
);
$this->scopeConfigMock = $this->getMockBuilder(ScopeConfigInterface::class)
->disableOriginalConstructor()
->getMock();
$this->urlModel = new Url($this->urlMockBuilder, $this->scopeConfigMock);
}
/**
* @param bool $withUrlKey
* @return \PHPUnit_Framework_MockObject_MockObject|\Sample\News\Model\Author
*/
protected function setUpAuthor($withUrlKey)
{
$author = $this->getMockBuilder(Author::class)
->disableOriginalConstructor()
->getMock();
$author->expects($this->any())->method('getId')->willReturn(1);
if ($withUrlKey) {
$author->expects($this->any())->method('getUrlKey')->willReturn(self::ITEM_URL_KEY);
}
return $author;
}
/**
* @test \Sample\News\Model\Author\Url::getListUrl()
*
* with SEF url key
*/
public function testGetListUrlWithSef()
{
$this->scopeConfigMock->expects($this->any())
->method('getValue')
->willReturn(self::LIST_URL_KEY);
$this->assertEquals('http://example.com/'.self::LIST_URL_KEY, $this->urlModel->getListUrl());
}
/**
* @test \Sample\News\Model\Author\Url::getListUrl()
*
* without SEF url key
*/
public function testGetListUrlWithoutSef()
{
$this->scopeConfigMock->expects($this->any())
->method('getValue')
->willReturn('');
$this->assertEquals('http://example.com/sample_news/author/index', $this->urlModel->getListUrl());
}
/**
* @test \Sample\News\Model\Author\Url::getAuthorUrl()
*
* without SEF url key
*/
public function testGetAuthorUrlWithoutSef()
{
$author = $this->setUpAuthor(false);
$author->expects($this->any())->method('getUrlKey')->willReturn('');
$this->assertEquals('http://example.com/sample_news/author/view/id/1', $this->urlModel->getAuthorUrl($author));
}
/**
* @test \Sample\News\Model\Author\Url::getAuthorUrl()
*
* with SEF url key: no prefix and no suffix
*/
public function testGetAuthorUrlWithSefNoSuffixNoPrefix()
{
$author = $this->setUpAuthor(true);
$this->scopeConfigMock->expects($this->any())
->method('getValue')
->willReturnMap(
[
[
Url::URL_PREFIX_CONFIG_PATH,
ScopeInterface::SCOPE_STORE,
''
],
[
Url::URL_SUFFIX_CONFIG_PATH,
ScopeInterface::SCOPE_STORE,
''
],
]
);
$this->assertEquals('http://example.com/' . self::ITEM_URL_KEY, $this->urlModel->getAuthorUrl($author));
}
/**
* @test \Sample\News\Model\Author\Url::getAuthorUrl()
*
* with SEF url key: with prefix and no suffix
*/
public function testGetAuthorUrlWithSefNoSuffixWithPrefix()
{
$author = $this->setUpAuthor(true);
$this->scopeConfigMock->expects($this->any())
->method('getValue')
->willReturnMap(
[
[
Url::URL_PREFIX_CONFIG_PATH,
ScopeInterface::SCOPE_STORE,
null,
'author'
],
[
Url::URL_SUFFIX_CONFIG_PATH,
ScopeInterface::SCOPE_STORE,
null,
''
],
]
);
$this->assertEquals('http://example.com/author/' . self::ITEM_URL_KEY, $this->urlModel->getAuthorUrl($author));
}
/**
* @test \Sample\News\Model\Author\Url::getAuthorUrl()
*
* with SEF url key: no prefix and with suffix
*/
public function testGetAuthorUrlWithSefWithSuffixNoPrefix()
{
$author = $this->setUpAuthor(true);
$this->scopeConfigMock->expects($this->any())
->method('getValue')
->willReturnMap(
[
[
Url::URL_PREFIX_CONFIG_PATH,
ScopeInterface::SCOPE_STORE,
null,
''
],
[
Url::URL_SUFFIX_CONFIG_PATH,
ScopeInterface::SCOPE_STORE,
null,
'html'
],
]
);
$this->assertEquals('http://example.com/' . self::ITEM_URL_KEY . '.html', $this->urlModel->getAuthorUrl($author));
}
/**
* @test \Sample\News\Model\Author\Url::getAuthorUrl()
*
* with SEF url key: with prefix and with suffix
*/
public function testGetAuthorUrlWithSefWithSuffixWithPrefix()
{
$author = $this->setUpAuthor(true);
$this->scopeConfigMock->expects($this->any())
->method('getValue')
->willReturnMap(
[
[
Url::URL_PREFIX_CONFIG_PATH,
ScopeInterface::SCOPE_STORE,
null,
'author'
],
[
Url::URL_SUFFIX_CONFIG_PATH,
ScopeInterface::SCOPE_STORE,
null,
'html'
],
]
);
$this->assertEquals('http://example.com/author/' . self::ITEM_URL_KEY . '.html', $this->urlModel->getAuthorUrl($author));
}
}
================================================
FILE: Test/Unit/Model/AuthorTest.php
================================================
objectManager = new ObjectManager($this);
/** @var \PHPUnit_Framework_MockObject_MockObject|Output $outputMock */
$outputMock = $this->getMockBuilder(Output::class)
->disableOriginalConstructor()
->getMock();
/** @var \PHPUnit_Framework_MockObject_MockObject||UploaderPool $uploaderPoolMock */
$uploaderPoolMock = $this->getMockBuilder(UploaderPool::class)
->disableOriginalConstructor()
->getMock();
/** @var \PHPUnit_Framework_MockObject_MockObject|Uploader $uploaderMock */
$uploaderMock = $this->getMockBuilder(Uploader::class)
->disableOriginalConstructor()
->getMock();
$uploaderMock->method('getBaseUrl')->willReturn('http://example/com/');
$uploaderMock->method('getBasePath')->willReturn('base/path');
$uploaderPoolMock->method('getUploader')->willReturn($uploaderMock);
/** @var \PHPUnit_Framework_MockObject_MockObject|Context $contextMock */
$contextMock = $this->getMockBuilder(Context::class)
->disableOriginalConstructor()
->getMock();
/** @var \PHPUnit_Framework_MockObject_MockObject|Registry $registryMock */
$registryMock = $this->getMockBuilder(Registry::class)
->disableOriginalConstructor()
->getMock();
/** @var \PHPUnit_Framework_MockObject_MockObject|FilterManager $filterManagerMock */
$filterManagerMock = $this->getMockBuilder(FilterManager::class)
->disableOriginalConstructor()
->getMock();
$filterManagerMock->method('translitUrl')->willReturn('dummy');
/** @var \PHPUnit_Framework_MockObject_MockObject||Url $urlMock */
$urlMock = $this->getMockBuilder(Url::class)
->disableOriginalConstructor()
->getMock();
$urlMock->method('getUrl')->willReturn('http://example.com/dummy');
$this->authorModel = $this->objectManager->getObject(
Author::class,
[
'context' => $contextMock,
'registry' => $registryMock,
'output' => $outputMock,
'uploaderPool' => $uploaderPoolMock,
'filterManager' => $filterManagerMock,
'url' => $urlMock
]
);
$data = $this->getAuthorData();
$this->authorModel->setData($data);
}
/**
* @return array
*/
protected function getAuthorData()
{
$data = [
'name' => 'John Doe',
'type' => '1',
'awards' => [1, 2],
'in_rss' => 1,
'is_active' => 1,
'country' => 'RO',
'biography' => 'Some biography
',
'dob' => '1983-08-18',
'url_key' => 'john-doe',
'avatar' => '/path/to/avatar.jpg',
'resume' => 'path/to/resume.pdf',
'created_at' => '2016-06-06 00:12:34',
'updated_at' => '2016-06-08 12:34:56',
'author_id' => 1,
'meta_title' => 'dummy meta title',
'meta_description' => 'dummy meta description',
'meta_keywords' => 'dummy meta keywords',
'store_id' => [0],
];
return $data;
}
/**
* @test class getters
*/
public function testGetters()
{
$data = $this->getAuthorData();
$this->assertEquals($data['name'], $this->authorModel->getName());
$this->assertEquals($data['awards'], $this->authorModel->getAwards());
$this->assertEquals($data['in_rss'], $this->authorModel->getInRss());
$this->assertEquals($data['is_active'], $this->authorModel->getIsActive());
$this->assertEquals($data['is_active'], $this->authorModel->isActive());
$this->assertEquals($data['country'], $this->authorModel->getCountry());
$this->assertEquals($data['biography'], $this->authorModel->getBiography());
$this->assertEquals($data['dob'], $this->authorModel->getDob());
$this->assertEquals($data['url_key'], $this->authorModel->getUrlKey());
$this->assertEquals($data['avatar'], $this->authorModel->getAvatar());
$this->assertEquals($data['resume'], $this->authorModel->getResume());
$this->assertEquals($data['created_at'], $this->authorModel->getCreatedAt());
$this->assertEquals($data['updated_at'], $this->authorModel->getUpdatedAt());
$this->assertEquals($data['meta_title'], $this->authorModel->getMetaTitle());
$this->assertEquals($data['meta_description'], $this->authorModel->getMetaDescription());
$this->assertEquals($data['meta_keywords'], $this->authorModel->getMetaKeywords());
$this->assertEquals($data['store_id'], $this->authorModel->getStoreId());
}
/**
* @test \Sample\News\Model\Author::getAvatarUrl()
*
* with null avatar
*/
public function testGetAvatarUrlWithNull()
{
$this->authorModel->setAvatar(null);
$this->assertFalse($this->authorModel->getAvatarUrl());
}
/**
* @test \Sample\News\Model\Author::getAvatarUrl()
*
* with string avatar
*/
public function testGetAvatarUrlWithString()
{
$this->authorModel->setAvatar('/avatar.jpg');
$this->assertEquals('http://example/com/base/path/avatar.jpg', $this->authorModel->getAvatarUrl());
}
/**
* @test \Sample\News\Model\Author::getAvatarUrl()
*
* with exception
*/
public function testGetAvatarUrlWithException()
{
$this->authorModel->setAvatar(['dummy']);
$this->setExpectedException('\Exception', __('Something went wrong while getting the avatar url.'));
$this->authorModel->getAvatarUrl();
}
/**
* @test \Sample\News\Model\Author::getResumeUrl()
*
* with null resume
*/
public function testGetResumeUrlWithNull()
{
$this->authorModel->setResume(null);
$this->assertFalse($this->authorModel->getResumeUrl());
}
/**
* @test \Sample\News\Model\Author::getResumeUrl()
*
* with string resume
*/
public function testGetResumeUrlWithString()
{
$this->authorModel->setResume('/resume.jpg');
$this->assertEquals('http://example/com/base/path/resume.jpg', $this->authorModel->getResumeUrl());
}
/**
* @test \Sample\News\Model\Author::getResumeUrl()
*
* with exception
*/
public function testGetResumeUrlWithException()
{
$this->authorModel->setResume(['dummy']);
$this->setExpectedException('\Exception', __('Something went wrong while getting the resume url.'));
$this->authorModel->getResumeUrl();
}
}
================================================
FILE: Test/Unit/Model/Source/CountryTest.php
================================================
objectManager = new ObjectManager($this);
$this->countryCollectionFactoryMock = $this->getMockBuilder(CollectionFactory::class)
->disableOriginalConstructor()
->getMock();
$countryMock = $this->getMockBuilder(CountryModel::class)
->disableOriginalConstructor()
->getMock();
$this->countryCollection = $this->objectManager->getCollectionMock(Collection::class, [$countryMock]);
$this->countryCollectionFactoryMock->method('create')->willReturn($this->countryCollection);
$this->countryList = new Country($this->countryCollectionFactoryMock);
}
/**
* @test \Sample\News\Model\Source\Country::toOptionArray result is memoized
*/
public function testMemoizedOptionArray()
{
$this->countryCollection->method('toOptionArray')->willReturn(['baz' => 'qux']);
$this->countryCollection->expects($this->once())->method('toOptionArray');
$result1 = $this->countryList->toOptionArray();
$result2 = $this->countryList->toOptionArray();
$this->assertSame($result1, $result2);
}
}
================================================
FILE: Test/Unit/Model/UploaderPoolTest.php
================================================
objectManager = new ObjectManager($this);
/** @var \PHPUnit_Framework_MockObject_MockObject|ObjectManagerInterface $objectManagerMock */
$objectManagerMock = $this->getMockBuilder(ObjectManagerInterface::class)
->disableOriginalConstructor()
->getMock();
/** @var \PHPUnit_Framework_MockObject_MockObject|Uploader $uploaderMock */
$uploaderMock = $this->getMockBuilder(Uploader::class)
->disableOriginalConstructor()
->getMock();
$objectManagerMock->expects($this->any())->method('create')->willReturn($uploaderMock);
$dataObject = new DataObject();
$this->uploaderPool = new UploaderPool(
$objectManagerMock,
[
'uploader1' => Uploader::class,
'uploader2' => $uploaderMock,
'uploader3' => $dataObject
]
);
}
/**
* @test \Sample\News\Model\UploaderPool::getUploader() when uploader is not found
* @throws \Exception
*/
public function testGetUploaderNotFound()
{
$type = 'test';
$this->setExpectedException('\Exception', "Uploader not found for type: ".$type);
$this->uploaderPool->getUploader($type);
}
/**
* @test \Sample\News\Model\UploaderPool::getUploader() when instantiation is needed
* @throws \Exception
*/
public function testGetUploaderInstantiationNeeded()
{
$type = 'uploader1';
$this->assertInstanceOf(Uploader::class, $this->uploaderPool->getUploader($type));
}
/**
* @test \Sample\News\Model\UploaderPool::getUploader() when instantiation is not needed
* @throws \Exception
*/
public function testGetUploaderInstantiationNotNeeded()
{
$type = 'uploader2';
$this->assertInstanceOf(Uploader::class, $this->uploaderPool->getUploader($type));
}
/**
* @test \Sample\News\Model\UploaderPool::getUploader() with wrong type returned
* @throws \Exception
*/
public function testGetUploaderWrongType()
{
$type = 'uploader3';
$this->setExpectedException('\Exception', "Uploader for type {$type} not instance of ".Uploader::class);
$this->uploaderPool->getUploader($type);
}
}
================================================
FILE: Test/Unit/Model/UploaderTest.php
================================================
getMockBuilder(Database::class)
->disableOriginalConstructor()
->getMock();
$coreFileStorageDatabaseMock->method('copyFile')->willReturn($coreFileStorageDatabaseMock);
/** @var \PHPUnit_Framework_MockObject_MockObject|Filesystem $fileSystemMock */
$fileSystemMock = $this->getMockBuilder(Filesystem::class)
->disableOriginalConstructor()
->getMock();
/** @var \PHPUnit_Framework_MockObject_MockObject|WriteInterface $writeInterfaceMock */
$writeInterfaceMock = $this->getMockBuilder(WriteInterface::class)
->disableOriginalConstructor()
->getMock();
$writeInterfaceMock->method('renameFile')->willReturn($writeInterfaceMock);
$fileSystemMock->method('getDirectoryWrite')->willReturn($writeInterfaceMock);
/** @var \PHPUnit_Framework_MockObject_MockObject|UploaderFactory $uploaderFactoryMock */
$uploaderFactoryMock = $this->getMockBuilder(UploaderFactory::class)
->disableOriginalConstructor()
->getMock();
/** @var \PHPUnit_Framework_MockObject_MockObject|Uploader $uploaderMock */
$uploaderMock = $this->getMockBuilder(Uploader::class)
->disableOriginalConstructor()
->getMock();
$uploaderMock->method('save')->willReturn([
'file' => 'file.ext',
'tmp_name' => 'file.ext',
'path' => 'path'
]);
$uploaderFactoryMock->method('create')->willReturn($uploaderMock);
/** @var \PHPUnit_Framework_MockObject_MockObject|StoreManagerInterface $storeManagerMock */
$storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class)
->disableOriginalConstructor()
->getMock();
/** @var \PHPUnit_Framework_MockObject_MockObject|Store $storeMock */
$storeMock = $this->getMockBuilder(Store::class)
->disableOriginalConstructor()
->getMock();
$storeMock->method('getBaseUrl')->willReturn('http://example.com/');
$storeManagerMock->method('getStore')->willReturn($storeMock);
/** @var \PHPUnit_Framework_MockObject_MockObject|LoggerInterface $loggerMock */
$loggerMock = $this->getMockBuilder(LoggerInterface::class)
->disableOriginalConstructor()
->getMock();
$this->uploader = new UploaderModel(
$coreFileStorageDatabaseMock,
$fileSystemMock,
$uploaderFactoryMock,
$storeManagerMock,
$loggerMock,
[],
self::BASE_TMP_PATH,
self::BASE_PATH
);
}
/**
* @test Sample\News\Model\Uploader::getBaseTmpPath()
*/
public function testGetBaseTmpPath()
{
$this->assertEquals(self::BASE_TMP_PATH, $this->uploader->getBaseTmpPath());
}
/**
* @test Sample\News\Model\Uploader::getBasePath
*/
public function testGetBasePath()
{
$this->assertEquals(self::BASE_PATH, $this->uploader->getBasePath());
}
/**
* @test Sample\News\Model\Uploader::getAllowedExtensions
*/
public function testGetAllowedExtensions()
{
$this->assertEquals([], $this->uploader->getAllowedExtensions());
$this->uploader->setAllowedExtensions(['ext']);
$this->assertEquals(['ext'], $this->uploader->getAllowedExtensions());
}
/**
* @test Sample\News\Model\Uploader::getFilePath
*/
public function testGetFilePath()
{
$this->assertEquals('path/here/file.ext', $this->uploader->getFilePath('path/here/', '/file.ext'));
$this->assertEquals('path/here/file.ext', $this->uploader->getFilePath('path/here', '/file.ext'));
$this->assertEquals('path/here/file.ext', $this->uploader->getFilePath('path/here/', 'file.ext'));
$this->assertEquals('path/here/file.ext', $this->uploader->getFilePath('path/here', 'file.ext'));
}
/**
* @test Sample\News\Model\Uploader::moveFileFromTmp
*/
public function testMoveFileFromTmp()
{
$this->assertEquals('dummy', $this->uploader->moveFileFromTmp('dummy'));
}
/**
* @test Sample\News\Model\Uploader::saveFileToTmpDir
*/
public function testSaveFileToTmpDir()
{
$expected = [
'file' => 'file.ext',
'tmp_name' => 'file.ext',
'path' => 'path',
'url' => 'http://example.com/base/tmp/path/file.ext'
];
$this->assertEquals($expected, $this->uploader->saveFileToTmpDir('dummy'));
}
/**
* @test Sample\News\Model\Uploader::uploadFileAndGetName
*/
public function testUploadFileAndGetName()
{
$data = [];
$this->assertEmpty($this->uploader->uploadFileAndGetName('dummy', $data));
$data = [
'dummy' => [
'delete' => 1,
'dummy1' => [
'data1', 'data2'
]
]
];
$this->assertEmpty($this->uploader->uploadFileAndGetName('dummy', $data));
$data = [
'dummy' => [
[
'name' => 'file.ext',
'tmp_name' => 'dummy',
'file' => 'file.ext'
]
]
];
$this->assertEquals('file.ext', $this->uploader->uploadFileAndGetName('dummy', $data));
}
}
================================================
FILE: Test/Unit/Ui/Component/Listing/Column/AuthorActionsTest.php
================================================
getMockBuilder(UrlInterface::class)
->disableOriginalConstructor()
->getMock();
/** @var \PHPUnit_Framework_MockObject_MockObject|ContextInterface $contextMock */
$contextMock = $this->getMockBuilder(ContextInterface::class)
->getMockForAbstractClass();
/** @var \PHPUnit_Framework_MockObject_MockObject|Processor $processor */
$processor = $this->getMockBuilder(Processor::class)
->disableOriginalConstructor()
->getMock();
$contextMock->expects($this->any())->method('getProcessor')->willReturn($processor);
/** @var \PHPUnit_Framework_MockObject_MockObject|UiComponentFactory $uiComponentFactoryMock */
$uiComponentFactoryMock = $this->getMockBuilder(UiComponentFactory::class)
->disableOriginalConstructor()
->getMock();
/** @var \Sample\News\Ui\Component\Listing\Column\AuthorActions $actions */
$actions = new AuthorActions($contextMock, $uiComponentFactoryMock, $urlBuilderMock);
// Define test input and expectations
$items = [
'data' => [
'items' => [
[
'author_id' => $authorId
]
]
]
];
$name = 'item_name';
$expectedItems = [
[
'author_id' => $authorId,
$name => [
'edit' => [
'href' => 'some/url/edit',
'label' => __('Edit'),
],
'delete' => [
'href' => 'some/url/delete',
'label' => __('Delete'),
'confirm' => [
'title' => __('Delete "${ $.$data.name }"'),
'message' => __('Are you sure you wan\'t to delete the Author "${ $.$data.name }" ?')
],
]
],
]
];
// Configure mocks and object data
$urlBuilderMock->expects($this->any())
->method('getUrl')
->willReturnMap(
[
[
AuthorActions::URL_PATH_EDIT,
[
'author_id' => $authorId
],
'some/url/edit',
],
[
AuthorActions::URL_PATH_DELETE,
[
'author_id' => $authorId
],
'some/url/delete',
],
]
);
$actions->setName($name);
$items = $actions->prepareDataSource($items);
// Run test
$this->assertEquals($expectedItems, $items['data']['items']);
}
}
================================================
FILE: Test/Unit/Ui/Component/Listing/Column/AvatarTest.php
================================================
getMockBuilder(ContextInterface::class)
->disableOriginalConstructor()
->getMock();
/** @var \PHPUnit_Framework_MockObject_MockObject|UiComponentFactory $uiComponentFactoryMock */
$uiComponentFactoryMock = $this->getMockBuilder(UiComponentFactory::class)
->disableOriginalConstructor()
->getMock();
/** @var \PHPUnit_Framework_MockObject_MockObject|UrlInterface $urlBuilderMock */
$urlBuilderMock = $this->getMockBuilder(UrlInterface::class)
->disableOriginalConstructor()
->getMock();
/** @var \PHPUnit_Framework_MockObject_MockObject|Uploader $uploaderMock */
$uploaderMock = $this->getMockBuilder(Uploader::class)
->disableOriginalConstructor()
->getMock();
$uploaderMock->method('getBasePath')->willReturn('/base/path');
$uploaderMock->method('getBaseUrl')->willReturn('http://example.com');
$processor = $this->getMockBuilder(Processor::class)
->disableOriginalConstructor()
->getMock();
$contextMock->expects($this->any())->method('getProcessor')->willReturn($processor);
/** @var \Sample\News\Ui\Component\Listing\Column\Avatar $avatarModel */
$avatarModel = new Avatar($contextMock, $uiComponentFactoryMock, $urlBuilderMock, $uploaderMock, [], []);
$authorId = 1;
$urlBuilderMock
->method('getUrl')
->willReturnMap(
[
[
AuthorActions::URL_PATH_EDIT,
[
'author_id' => $authorId
],
'some/url/here',
],
]
);
$fieldName = 'avatar';
$avatarModel->setName($fieldName);
$items = [
'data' => [
'items' => [
[
'author_id' => $authorId,
$fieldName => '/some/image.jpg',
'name' => 'test name',
]
]
]
];
$expectedResult = [
'data' => [
'items' => [
[
'author_id' => $authorId,
$fieldName => '/some/image.jpg',
'name' => 'test name',
$fieldName . '_src' => 'http://example.com/base/path/some/image.jpg',
$fieldName . '_alt' => 'test name',
$fieldName . '_link' => 'some/url/here',
$fieldName . '_orig_src' => 'http://example.com/base/path/some/image.jpg'
]
]
]
];
$items = $avatarModel->prepareDataSource($items);
$this->assertEquals($expectedResult, $items);
}
}
================================================
FILE: Test/Unit/Ui/Component/Listing/Column/Store/OptionsTest.php
================================================
systemStoreMock = $this->getMockBuilder(Store::class)
->disableOriginalConstructor()
->getMock();
$this->websiteMock = $this->getMock(
Website::class,
['getId', 'getName'],
[],
'',
false
);
$this->groupMock = $this->getMock(Group::class, [], [], '', false);
$this->storeMock = $this->getMock(StoreModel::class, [], [], '', false);
$this->escaperMock = $this->getMock(Escaper::class, [], [], '', false);
$this->options = new Options($this->systemStoreMock, $this->escaperMock);
}
/**
* @test Sample\News\Ui\Component\Listing\Column\Store\Options::toOptionArray()
*/
public function testToOptionArray()
{
$websiteCollection = [$this->websiteMock];
$groupCollection = [$this->groupMock];
$storeCollection = [$this->storeMock];
$expectedOptions = [
[
'label' => __('All Store Views'),
'value' => '0'
],
[
'label' => 'Main Website',
'value' => [
[
'label' => ' Main Website Store',
'value' => [
[
'label' => ' Default Store View',
'value' => '1'
]
]
]
]
]
];
$this->systemStoreMock->expects($this->once())->method('getWebsiteCollection')->willReturn($websiteCollection);
$this->systemStoreMock->expects($this->once())->method('getGroupCollection')->willReturn($groupCollection);
$this->systemStoreMock->expects($this->once())->method('getStoreCollection')->willReturn($storeCollection);
$this->websiteMock->expects($this->atLeastOnce())->method('getId')->willReturn('1');
$this->websiteMock->expects($this->any())->method('getName')->willReturn('Main Website');
$this->groupMock->expects($this->atLeastOnce())->method('getWebsiteId')->willReturn('1');
$this->groupMock->expects($this->atLeastOnce())->method('getId')->willReturn('1');
$this->groupMock->expects($this->atLeastOnce())->method('getName')->willReturn('Main Website Store');
$this->storeMock->expects($this->atLeastOnce())->method('getGroupId')->willReturn('1');
$this->storeMock->expects($this->atLeastOnce())->method('getName')->willReturn('Default Store View');
$this->storeMock->expects($this->atLeastOnce())->method('getId')->willReturn('1');
$this->escaperMock->expects($this->atLeastOnce())->method('escapeHtml')->willReturnMap(
[
['Default Store View', null, 'Default Store View'],
['Main Website Store', null, 'Main Website Store'],
['Main Website', null, 'Main Website']
]
);
$this->assertEquals($expectedOptions, $this->options->toOptionArray());
}
}
================================================
FILE: Test/Unit/Ui/DataProvider/Author/Form/Modifier/AuthorDataTest.php
================================================
objectManager = new ObjectManager($this);
$this->collectionFactoryMock = $this->getMockBuilder(CollectionFactory::class)
->disableOriginalConstructor()
->getMock();
$authorData = [
'author_id' => 1,
'name' => 'test',
'avatar' => '/some/image.jpg',
'resume' => '/some/file.txt'
];
$mockAuthor = $this->getMock(
Author::class,
[],
[],
'',
false
);
$mockAuthor->method('getData')->willReturn($authorData);
$mockAuthor->method('getId')->willReturn($authorData['author_id']);
$mockAuthor->method('getAvatarUrl')->willReturn('http://example.com'.$authorData['avatar']);
$mockAuthor->method('getAvatar')->willReturn($authorData['avatar']);
$mockAuthor->method('getResumeUrl')->willReturn('http://example.com'.$authorData['resume']);
$mockAuthor->method('getResume')->willReturn($authorData['resume']);
$collectionMock = $this->objectManager->getCollectionMock(
Collection::class,
[$mockAuthor]
);
$collectionMock->method('getItems')->willReturn([$mockAuthor]);
$this->collectionFactoryMock->method('create')->willReturn($collectionMock);
$this->authorDataModifier = new AuthorData($this->collectionFactoryMock);
}
/**
* @test Sample\News\Ui\DataProvider\Author\Form\Modifier\AuthorData::AuthorData::modfyMeta()
*/
public function testModifyMeta()
{
$this->assertEquals(
$this->getSampleData(),
$this->authorDataModifier->modifyMeta($this->getSampleData())
);
}
/**
* @test modifyData method
*/
public function testModifiyData()
{
$expected = [
'key' => 'value',
'1' => [
'author_id' => 1,
'name' => 'test',
'avatar' => [
0 => [
'name' => '/some/image.jpg',
'url' => 'http://example.com/some/image.jpg'
]
],
'resume' => [
0 => [
'name' => '/some/file.txt',
'url' => 'http://example.com/some/file.txt'
]
]
]
];
$data = $this->authorDataModifier->modifyData($this->getSampleData());
$this->assertEquals($expected, $data);
}
/**
* @return array
*/
protected function getSampleData()
{
return ['key' => 'value'];
}
}
================================================
FILE: Ui/Component/Listing/Column/AuthorActions.php
================================================
_urlBuilder = $urlBuilder;
parent::__construct($context, $uiComponentFactory, $components, $data);
}
/**
* Prepare Data Source
*
* @param array $dataSource
* @return array
*/
public function prepareDataSource(array $dataSource)
{
if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as & $item) {
if (isset($item['author_id'])) {
$item[$this->getData('name')] = [
'edit' => [
'href' => $this->_urlBuilder->getUrl(
static::URL_PATH_EDIT,
[
'author_id' => $item['author_id']
]
),
'label' => __('Edit')
],
'delete' => [
'href' => $this->_urlBuilder->getUrl(
static::URL_PATH_DELETE,
[
'author_id' => $item['author_id']
]
),
'label' => __('Delete'),
'confirm' => [
'title' => __('Delete "${ $.$data.name }"'),
'message' => __('Are you sure you wan\'t to delete the Author "${ $.$data.name }" ?')
]
]
];
}
}
}
return $dataSource;
}
}
================================================
FILE: Ui/Component/Listing/Column/Avatar.php
================================================
imageModel = $imageModel;
$this->urlBuilder = $urlBuilder;
parent::__construct($context, $uiComponentFactory, $components, $data);
}
/**
* Prepare Data Source
*
* @param array $dataSource
* @return array
*/
public function prepareDataSource(array $dataSource)
{
if(isset($dataSource['data']['items'])) {
$fieldName = $this->getData('name');
foreach($dataSource['data']['items'] as & $item) {
$url = '';
if($item[$fieldName] != '') {
$url = $this->imageModel->getBaseUrl().$this->imageModel->getBasePath().$item[$fieldName];
}
$item[$fieldName . '_src'] = $url;
$item[$fieldName . '_alt'] = $this->getAlt($item) ?: '';
$item[$fieldName . '_link'] = $this->urlBuilder->getUrl(
'sample_news/author/edit',
['author_id' => $item['author_id']]
);
$item[$fieldName . '_orig_src'] = $url;
}
}
return $dataSource;
}
/**
* @param array $row
*
* @return null|string
*/
protected function getAlt($row)
{
$altField = $this->getData('config/altField') ?: self::ALT_FIELD;
return isset($row[$altField]) ? $row[$altField] : null;
}
}
================================================
FILE: Ui/Component/Listing/Column/Store/Options.php
================================================
options !== null) {
return $this->options;
}
$this->currentOptions['All Store Views']['label'] = __('All Store Views');
$this->currentOptions['All Store Views']['value'] = self::ALL_STORE_VIEWS;
$this->generateCurrentOptions();
$this->options = array_values($this->currentOptions);
return $this->options;
}
}
================================================
FILE: Ui/DataProvider/Author/Form/Modifier/AuthorData.php
================================================
collection = $authorCollectionFactory->create();
}
/**
* @param array $meta
* @return array
*/
public function modifyMeta(array $meta)
{
return $meta;
}
/**
* @param array $data
* @return array|mixed
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function modifyData(array $data)
{
$items = $this->collection->getItems();
/** @var $author \Sample\News\Model\Author */
foreach ($items as $author) {
$_data = $author->getData();
if (isset($_data['avatar'])) {
$avatar = [];
$avatar[0]['name'] = $author->getAvatar();
$avatar[0]['url'] = $author->getAvatarUrl();
$_data['avatar'] = $avatar;
}
if (isset($_data['resume'])) {
$resume = [];
$resume[0]['name'] = $author->getResume();
$resume[0]['url'] = $author->getResumeUrl();
$_data['resume'] = $resume;
}
$author->setData($_data);
$data[$author->getId()] = $_data;
}
return $data;
}
}
================================================
FILE: composer.json
================================================
{
"name": "sample/module-news",
"description": "Magento 2 Sample crud module",
"version": "2.0.0",
"license": "MIT",
"require": {
"php": "~5.6.0|7.0.2|~7.0.6",
"magento/module-backend": "100.1.*",
"magento/module-cms": "101.0.*",
"magento/module-ui": "100.1.*",
"magento/module-store": "100.1.*",
"magento/framework": "100.1.*",
"magento/module-media-storage": "100.1.*",
"magento/module-directory": "100.1.*",
"magento/module-customer": "100.1.*",
"magento/module-rss": "100.1.*"
},
"type": "magento2-module",
"repositories": [
{
"type": "git",
"url": "https://github.com/tzyganu/Magento2SampleModule"
}
],
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"Sample\\News\\": ""
}
}
}
================================================
FILE: etc/acl.xml
================================================
================================================
FILE: etc/adminhtml/di.xml
================================================
-
- Sample\News\Ui\DataProvider\Author\Form\Modifier\AuthorData
- 10
SampleNewsUiDataProviderAuthorFormModifierPool
A total of %1 record(s) have been deleted.
An error occurred while deleting record(s).
A total of %1 authors have been disabled.
An error occurred while disabling authors.
A total of %1 authors have been enabled.
An error occurred while enabling authors.
================================================
FILE: etc/adminhtml/menu.xml
================================================
================================================
FILE: etc/adminhtml/routes.xml
================================================
================================================
FILE: etc/adminhtml/system.xml
================================================
sample_news
Sample_News::news
Magento\Config\Model\Config\Source\Yesno
================================================
FILE: etc/config.xml
================================================
1
Authors
Authors Description Here
Authors Keywords Here
authors.html
author
html
1
600
================================================
FILE: etc/di.xml
================================================
- Sample\News\Model\ResourceModel\Author\Grid\Collection
sample_news_author
sample_news_author_grid_collection
author_grid_collection
Sample\News\Model\ResourceModel\Author
Sample\News\Model\Uploader::IMAGE_TMP_PATH
Sample\News\Model\Uploader::IMAGE_PATH
- jpg
- jpeg
- gif
- png
SampleNewsAuthorImageUploader
Sample\News\Model\Uploader::FILE_TMP_PATH
Sample\News\Model\Uploader::FILE_PATH
SampleNewsAuthorFileUploader
- SampleNewsAuthorImageUploader
- SampleNewsAuthorFileUploader
Sample\News\Model\UploaderPool
Sample\News\Model\UploaderPool
- SampleNewsModelAuthorSourceAward
- SampleNewsModelAuthorSourceType
- Sample\News\Model\Source\Country
SampleNewsAuthorImageUploader
Magento\Widget\Model\Template\Filter
-
- 1
- Award 1
-
- 2
- Award 2
-
- 3
- Award 3
-
- 1
- Collaborator
-
- 2
- Employee
-
- Sample\News\Model\Author::STATUS_ENABLED
- Yes
-
- Sample\News\Model\Author::STATUS_DISABLED
- No
- Sample\News\Block\Author\ListAuthor\Rss
SampleNewsAuthorImageUploader
author
SampleNewsBlockAuthorImageBuilder
================================================
FILE: etc/frontend/di.xml
================================================
-
- Sample\News\Controller\Router
- false
- 10
Sample\News\Model\Author\Url::URL_PREFIX_CONFIG_PATH
Sample\News\Model\Author\Url::URL_SUFFIX_CONFIG_PATH
Sample\News\Model\Author\Url::LIST_URL_CONFIG_PATH
Sample\News\Model\AuthorFactory
author
- SampleNewsRoutingEntityAuthor
================================================
FILE: etc/frontend/routes.xml
================================================
================================================
FILE: etc/module.xml
================================================
================================================
FILE: i18l/en_US.csv
================================================
"A total of %1 authors have been disabled.","A total of %1 authors have been disabled."
"A total of %1 record(s) have been deleted.","A total of %1 record(s) have been deleted."
"A total of %1 authors have been enabled.","A total of %1 authors have been enabled."
"Add New Author","Add New Author"
"All Store Views","All Store Views"
"An error occurred while deleting record(s).","An error occurred while deleting record(s)."
"An error occurred while disabling authors.","An error occurred while disabling authors."
"An error occurred while enabling authors.","An error occurred while enabling authors."
"Are you sure you want to delete selected items?","Are you sure you want to delete selected items?"
"Are you sure you want to delete the Author ""${ $.$data.name }"" ?","Are you sure you want to delete the Author ""${ $.$data.name }"" ?"
"Are you sure you want to do this?","Are you sure you want to do this?"
"Author in Store views","Author in Store views"
"Author Information","Author Information"
Authors,Authors
Avatar,Avatar
"Award 1","Award 1"
"Award 2","Award 2"
"Award 3","Award 3"
Awards,Awards
Back,Back
Biography,Biography
Collaborator,Collaborator
"Could not save the author: %1","Could not save the author: %1"
Country,Country
"Created At","Created At"
"Date of birth","Date of birth"
Delete,Delete
"Delete Author","Delete Author"
"Delete items","Delete items"
"Delete ""${ $.$data.name }""","Delete ""${ $.$data.name }"""
Disable,Disable
DOB,DOB
Edit,Edit
"Edit Author","Edit Author"
Employee,Employee
Enable,Enable
"Enter full name here","Enter full name here"
"File can not be saved to the destination folder.","File can not be saved to the destination folder."
Home,Home
ID,ID
"In RSS","In RSS"
"Is Active","Is Active"
label,label
"Meta Description","Meta Description"
"Meta Keywords","Meta Keywords"
"Meta Title","Meta Title"
Name,Name
"New Author","New Author"
News,News
No,No
"Please correct the data sent.","Please correct the data sent."
"Requested author doesn't exist","Requested author doesn't exist"
Reset,Reset
Resume,Resume
"Save Author","Save Author"
"Save and Continue Edit","Save and Continue Edit"
"Show In RSS","Show In RSS"
"Something went wrong while getting the avatar url.","Something went wrong while getting the avatar url."
"Something went wrong while getting the resume url.","Something went wrong while getting the resume url."
"Something went wrong while saving the author.","Something went wrong while saving the author."
"Something went wrong while saving the file(s).","Something went wrong while saving the file(s)."
"Store View","Store View"
"Subscribe to RSS Feed","Subscribe to RSS Feed"
"There are no authors at this moment","There are no authors at this moment"
"The author has been deleted.","The author has been deleted."
"The author no longer exists.","The author no longer exists."
"There was a problem deleting the author","There was a problem deleting the author"
"There was a problem saving the author","There was a problem saving the author"
Type,Type
"Unable to remove author %1","Unable to remove author %1"
"Updated At","Updated At"
"URL Key","URL Key"
"Url Key","Url Key"
"We can't find a author to delete.","We can't find a author to delete."
Yes,Yes
"You saved the author","You saved the author"
================================================
FILE: registration.php
================================================
================================================
FILE: view/adminhtml/layout/sample_news_author_index.xml
================================================
Sample_News::authors
complex
================================================
FILE: view/adminhtml/ui_component/sample_news_author_form.xml
================================================
================================================
FILE: view/adminhtml/ui_component/sample_news_author_listing.xml
================================================
-
- sample_news_author_listing.sample_news_author_listing_data_source
- sample_news_author_listing.sample_news_author_listing_data_source
- sample_news_author_columns
-
-
- add
- Add New Author
- primary
- */*/new
Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider
sample_news_author_listing_data_source
author_id
author_id
-
- Magento_Ui/js/grid/provider
-
- author_id
-
- Magento_Ui/js/grid/provider
-
- ui/grid/toolbar
- ui/grid/sticky/toolbar
-
-
- sample_news_author_listing
-
-
- sample_news_author_listing.sample_news_author_listing.sample_news_author_columns
- Magento_Ui/js/grid/controls/columns
- dataGridActions
-
- sample_news_author_listing.sample_news_author_listing_data_source
- sample_news_author_listing.sample_news_author_listing.listing_top.listing_filters_chips
-
- sample_news_author_listing.sample_news_author_listing.listing_top.bookmarks
- current.search
-
- sample_news_author_listing.sample_news_author_listing.sample_news_author_columns
-
- sample_news_author_listing.sample_news_author_listing.listing_top.bookmarks
- current.filters
-
-
-
- Magento_Ui/js/form/element/ui-select
- ui/grid/filters/elements/ui-select
-
- sample_news_author_listing.sample_news_author_listing.listing_top.listing_filters
-
- sample_news_author_listing.sample_news_author_listing.sample_news_author_columns.${ $.index }:visible
-
- column
Sample\News\Ui\Component\Listing\Column\Store\Options
-
- ${ $.parentName }
-
- componentType = column, index = ${ $.index }:visible
- store_id
- Store View
- 0
-
- sample_news_author_listing.sample_news_author_listing.sample_news_author_columns.ids
- author_id
-
- delete
- Delete
-
- Delete items
- Are you sure you want to delete selected items?
-
- disable
- Disable
-
- enable
- Enable
-
- edit
- Edit
-
- sample_news_author_listing.sample_news_author_listing.sample_news_author_columns_editor
- editSelected
-
-
- sample_news_author_listing.sample_news_author_listing.listing_top.bookmarks
- current.paging
- sample_news_author_listing.sample_news_author_listing.sample_news_author_columns.ids
-
-
- sample_news_author_listing.sample_news_author_listing.listing_top.bookmarks
- current
-
- sample_news_author_listing.sample_news_author_listing.sample_news_author_columns.ids
- true
- author_id
-
- false
-
-
- sample_news_author_listing.sample_news_author_listing.sample_news_author_columns_editor
- startEdit
-
- ${ $.$data.rowIndex }
- true
-
- sample_news_author_listing.sample_news_author_listing.listing_top.bookmarks
- columns.${ $.index }
- current.${ $.storageConfig.root}
-
- false
- 55
- author_id
-
- Magento_Ui/js/grid/columns/column
-
- textRange
- text
- asc
- left
- ID
-
- Magento_Ui/js/grid/columns/column
-
-
- text
-
- true
- text
- text
- left
- Name
-
- Magento_Ui/js/grid/columns/column
-
- text
- text
- text
- left
- Url Key
-
- ui/grid/cells/html
- false
- Store View
-
- Magento_Ui/js/grid/columns/date
-
- date
- dateRange
- date
- left
- DOB
- SampleNewsModelAuthorSourceType
-
- select
- select
- select
- Magento_Ui/js/grid/columns/select
- left
- Type
- Sample\News\Model\Source\Country
-
- select
- select
- select
- Magento_Ui/js/grid/columns/select
- left
- Country
- SampleNewsModelAuthorSourceIsActive
-
- select
- Magento_Ui/js/grid/columns/select
- select
- select
- Is Active
- Magento\Config\Model\Config\Source\Yesno
-
- select
- select
- select
- Magento_Ui/js/grid/columns/select
- left
- In RSS
-
- Magento_Ui/js/grid/columns/thumbnail
- false
- name
- 1
- Avatar
-
- Magento_Ui/js/grid/columns/date
-
- dateRange
- date
- left
- Created At
-
- Magento_Ui/js/grid/columns/date
-
- dateRange
- date
- left
- Updated At
-
- author_id
- author_id
================================================
FILE: view/adminhtml/web/template/file-preview.html
================================================
================================================
FILE: view/adminhtml/web/template/image-preview.html
================================================
================================================
FILE: view/frontend/layout/sample_news_author_index.xml
================================================
================================================
FILE: view/frontend/layout/sample_news_author_view.xml
================================================
================================================
FILE: view/frontend/templates/author/list.phtml
================================================
getAuthors(); ?>
getSize() > 0) :?>
getPagerHtml(); ?>
getPagerHtml(); ?>
================================================
FILE: view/frontend/templates/author/view.phtml
================================================
getCurrentAuthor();?>
: getName();?>
getAttributeText('type')) :?>
:
getProcessedBiography()) :?>
:
getDob()) :?>
: formatDate($dob, \IntlDateFormatter::LONG);?>
getAttributeText('awards')) :?>
:
getAttributeText('country')) :?>
:
getResume()) :?>
getImage($_author, 'author_view', ['width' => 100, 'height' => 100, 'type' => 'avatar'])->toHtml(); ?>
================================================
FILE: view/frontend/templates/image.phtml
================================================
getCustomAttributes(); ?>
src="getImageUrl(); ?>"
width="getWidth(); ?>"
height="getHeight(); ?>"
alt="stripTags($block->getLabel(), null, true); ?>" />
================================================
FILE: view/frontend/templates/image_with_borders.phtml
================================================
getCustomAttributes(); ?>
src="getImageUrl(); ?>"
width="getResizedImageWidth(); ?>"
height="getResizedImageHeight(); ?>"
alt="stripTags($block->getLabel(), null, true); ?>"/>
================================================
FILE: view/frontend/templates/rss/link.phtml
================================================
isRssEnabled()) : ?>