first commit

This commit is contained in:
2024-10-28 22:14:22 +01:00
commit b65352c452
40581 changed files with 5712079 additions and 0 deletions

16
modules/jxblog/.listing Normal file
View File

@@ -0,0 +1,16 @@
drwxr-xr-x 9 30094 users 16 Oct 6 10:16 .
drwxr-xr-x 115 30094 users 117 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 17685 Aug 31 2021 LICENSE.txt
-rw-r--r-- 1 30094 users 916 Aug 31 2021 Readme.md
drwxr-xr-x 2 30094 users 7 Oct 6 10:16 classes
-rw-r--r-- 1 30094 users 630 Aug 31 2021 config.xml
-rw-rw-r-- 1 30094 users 630 Aug 31 2021 config_pl.xml
drwxr-xr-x 4 30094 users 4 Oct 6 10:16 controllers
drwxr-xr-x 2 30094 users 3 Oct 6 10:16 helper
drwxr-xr-x 6 30094 users 6 Oct 6 10:16 img
-rw-r--r-- 1 30094 users 891 Aug 31 2021 index.php
-rw-r--r-- 1 30094 users 16841 Aug 31 2021 jxblog.php
-rw-r--r-- 1 30094 users 7625 Aug 31 2021 logo.png
drwxr-xr-x 2 30094 users 6 Oct 6 10:16 src
drwxr-xr-x 2 30094 users 9 Oct 6 10:16 translations
drwxr-xr-x 6 30094 users 7 Oct 6 10:16 views

124
modules/jxblog/LICENSE.txt Normal file
View File

@@ -0,0 +1,124 @@
The GNU General Public License (GPL-2.0)
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and modification follow.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.
You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.
In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
One line to give the program's name and a brief idea of what it does.
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker.
signature of Ty Coon, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.

32
modules/jxblog/Readme.md Normal file
View File

@@ -0,0 +1,32 @@
# JX Blog
v 1.1.2
UPD: removed Translator parameter from Repository class in order to reach compatibility with PS 1.7.6.1
v 1.1.1
UPD: admin tab management improved
FIX:
- fixed an issue with duplicating post categories if pick default category the same as one of the related
- fixed an issue with a searching through the JX Blog
v 1.1.0
UPD: - added an opportunity to create and use multilevel categories with no depth limit
- added compatibility to support new feature in posts
v 1.0.2
FIX:
- added notification that only .jpg images are allowed for categories
- added cache removing for post thumbnails preview
v 1.0.1
FIX:
- added workaround to avoid an issue with breadcrumbs items translation
1.0.0
UPD:
- tested all features
- added new blog home page option with new template and controller
0.0.2
FIX: fixed an issue with PHP 7 compatibility(admin part). An error with setMedia conformity

View File

@@ -0,0 +1,7 @@
drwxr-xr-x 2 30094 users 7 Oct 6 10:16 .
drwxr-xr-x 9 30094 users 16 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 17253 Aug 31 2021 JXBlogCategory.php
-rw-r--r-- 1 30094 users 4016 Aug 31 2021 JXBlogImage.php
-rw-r--r-- 1 30094 users 12805 Aug 31 2021 JXBlogImageManager.php
-rw-r--r-- 1 30094 users 27664 Aug 31 2021 JXBlogPost.php
-rw-r--r-- 1 30094 users 2087 Aug 31 2021 JXBlogTag.php

View File

@@ -0,0 +1,438 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class JXBlogCategory extends ObjectModel
{
public $module;
public $id;
public $id_jxblog_category;
public $id_parent_category;
public $active;
public $position;
public $date_add;
public $date_upd;
public $name;
public $description;
public $short_description;
public $link_rewrite;
public $meta_keyword;
public $meta_description;
public $badge;
public static $definition = array(
'table' => 'jxblog_category',
'primary' => 'id_jxblog_category',
'multilang' => true,
'fields' => array(
'active' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'position' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
'id_parent_category' => array('type' => self::TYPE_INT, 'required' => true, 'validate' => 'isUnsignedId'),
'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
'date_upd' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
'name' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isCatalogName', 'required' => true, 'size' => 128),
'description' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'),
'short_description' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'),
'link_rewrite' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isLinkRewrite', 'required' => true),
'meta_keyword' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isString'),
'meta_description' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isString'),
'badge' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isString')
)
);
public function __construct($id = null, $id_lang = null, $id_shop = null)
{
$this->module = new Jxblog();
Shop::addTableAssociation('jxblog_category', array('type' => 'shop'));
parent::__construct($id, $id_lang, $id_shop);
}
public function add($auto_date = true, $null_values = false)
{
Hook::exec('actionJxblogCategoryBeforeAdd', array('id_jxblog_category' => $this->id));
$res = parent::add($auto_date, $null_values);
$res &= $this->associateToGroup();
Hook::exec('actionJxblogCategoryAfterAdd', array('id_jxblog_category' => $this->id));
return $res;
}
public function update($null_values = false)
{
Hook::exec('actionJxblogCategoryBeforeUpdate', array('id_jxblog_category' => $this->id));
$res = parent::update($null_values);
// avoid data removing during status updating within ajax
if (!Tools::getIsset('action') || Tools::getValue('action') != 'statusjxblog_category') {
$res &= $this->associateToGroup();
}
Hook::exec('actionJxblogCategoryAfterUpdate', array('id_jxblog_category' => $this->id));
return $res;
}
public function delete()
{
Hook::exec('actionJxblogCategoryBeforeDelete', array('id_jxblog_category' => $this->id));
$imageManager = new JXBlogImageManager($this->module);
$result = parent::delete();
$result &= $this->removeAssociationGroup();
$result &= $imageManager->removeImages($this->id, 'category');
$result &= $imageManager->removeImages($this->id, 'category_thumb');
Hook::exec('actionJxblogCategoryAfterDelete', array('id_jxblog_category' => $this->id));
return $result;
}
/**
* Check a category name existence to avoid name duplication
*
* @param $name
* @param $id_lang
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public function checkCategoryNameExistence($id_jxblog_category, $name, $id_lang)
{
$extend = '';
if ($id_jxblog_category) {
$extend = ' AND `id_jxblog_category` != '.(int)$id_jxblog_category;
}
$sql = 'SELECT `id_jxblog_category`
FROM '._DB_PREFIX_.'jxblog_category_lang
WHERE `name` = "'.pSql($name).'"
AND `id_lang` = '.(int)$id_lang.$extend;
return Db::getInstance()->executeS($sql);
}
/**
* Check a category friendly URL existence to avoid duplication
*
* @param $url
* @param $id_lang
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public function checkFriendlyUrlNameExistence($id_jxblog_category, $url, $id_lang)
{
$extend = '';
if ($id_jxblog_category) {
$extend = ' AND `id_jxblog_category` != '.(int)$id_jxblog_category;
}
$sql = 'SELECT `id_jxblog_category`
FROM '._DB_PREFIX_.'jxblog_category_lang
WHERE `link_rewrite` = "'.pSql($url).'"
AND `id_lang` = '.(int)$id_lang.$extend;
return Db::getInstance()->executeS($sql);
}
/**
* Associate current category to all selected groups
*
* @return bool
* @throws PrestaShopDatabaseException
*/
public function associateToGroup()
{
$groups = Tools::getValue('groupBox');
if (!$this->removeAssociationGroup()) {
return false;
}
if ($groups && count($groups) > 0) {
foreach ($groups as $group) {
if (!Db::getInstance()->getValue(
'SELECT * FROM '._DB_PREFIX_.'jxblog_category_group WHERE `id_jxblog_category` = '.$this->id.' AND `id_group` = '.$group
)
) {
if (!Db::getInstance()->insert(
'jxblog_category_group',
array('id_jxblog_category' => (int)$this->id, 'id_group' => (int)$group)
)
) {
return false;
}
}
}
}
return true;
}
/**
* Remove current category from groups associations
*
* @return bool
*/
public function removeAssociationGroup()
{
return Db::getInstance()->delete('jxblog_category_group', '`id_jxblog_category` = '.(int)$this->id.'');
}
/**
* Get all groups to which current category is related to
*
* @return array|null
* @throws PrestaShopDatabaseException
*/
public function getGroups()
{
$cacheId = 'JXBlogCategory::getGroups_'.(int)$this->id;
if (!Cache::isStored($cacheId)) {
$sql = new DbQuery();
$sql->select('jxbcg.`id_group`');
$sql->from('jxblog_category_group', 'jxbcg');
$sql->where('jxbcg.`id_jxblog_category` = '.(int)$this->id);
$result = Db::getInstance()->executeS($sql);
$groups = array();
foreach ($result as $group) {
$groups[] = $group['id_group'];
}
Cache::store($cacheId, $groups);
return $groups;
}
return Cache::retrieve($cacheId);
}
/**
* Update positions of all categories after any category position was changed
*
* @param $way decrease || increase position of changing category
* @param $position new position of changing category
* @param $id_parent use parent category filter
*
* @return bool
* @throws PrestaShopDatabaseException
*/
public function updatePosition($way, $position)
{
// get parent id to know sorting scope
$id_parent = Db::getInstance()->getValue(
'SELECT `id_parent_category`
FROM `'._DB_PREFIX_.'jxblog_category`
WHERE `id_jxblog_category` = '.(int)$this->id
);
// select all available blog categories and their positions
if (!$res = Db::getInstance()->executeS(
'
SELECT `id_jxblog_category`, `position`
FROM `'._DB_PREFIX_.'jxblog_category`
WHERE `id_parent_category` = '.(int)$id_parent.'
ORDER BY `position` ASC'
)
) {
return false;
}
// mark the category which is moving
$categoryMoved = false;
foreach ($res as $category) {
if ((int)$category['id_jxblog_category'] == (int)$this->id) {
$categoryMoved = $category;
}
}
if ($categoryMoved === false) {
return false;
}
// update all categories' positions, but not that one which is moving
$result = Db::getInstance()->execute(
'
UPDATE '._DB_PREFIX_.'jxblog_category
SET `position` = `position` '.($way ? '-1' : '+1').', `date_upd` = "'.date('Y-m-d H:i:s').'"
WHERE `position` '.($way
? '> '.(int)$categoryMoved['position'].' AND `position` <= '.(int)$position
: '< '.(int)$categoryMoved['position'].' AND `position` >= '.(int)$position).'
AND `id_parent_category` = '.(int)$id_parent
);
// update position of the moving category
$result &= Db::getInstance()->execute(
'UPDATE `'._DB_PREFIX_.'jxblog_category`
SET `position` = '.(int)$position.',
`date_upd` = "'.date('Y-m-d H:i:s').'"
WHERE `id_jxblog_category` = '.(int)$categoryMoved['id_jxblog_category'].'
AND `id_parent_category` = '.(int)$id_parent
);
return $result;
}
/**
* Get the maximum position of already existing categories to set it + 1 to a new category
*
* @param $id_parent
*
* @return false|int|null|string
*/
public function getNewPosition($id_parent = 2)
{
$sql = 'SELECT MAX(`position`)
FROM '._DB_PREFIX_.'jxblog_category
WHERE `id_parent_category` = '.(int)$id_parent;
$max = Db::getInstance()->getValue($sql);
if ($max === null) {
return 0;
}
return $max + 1;
}
public static function getAllCategories()
{
return Db::getInstance()->executeS('SELECT `id_jxblog_category` AS `id` FROM '._DB_PREFIX_.'jxblog_category');
}
public static function getAllCategoriesWithInfo()
{
return Db::getInstance()->executeS(
'
SELECT c.*, cl.* FROM '._DB_PREFIX_.'jxblog_category c
LEFT JOIN '._DB_PREFIX_.'jxblog_category_lang cl
ON(cl.`id_jxblog_category`=c.`id_jxblog_category`)
WHERE cl.`id_lang` = '.Context::getContext()->language->id
);
}
public static function getAllFrontCategories($id_parent, $id_lang, $id_shop, $id_group, $page = 0, $limit = 10)
{
return Db::getInstance()->executeS(
'
SELECT c.*, cl.*
FROM '._DB_PREFIX_.'jxblog_category c
LEFT JOIN '._DB_PREFIX_.'jxblog_category_lang cl
ON(c.`id_jxblog_category` = cl.`id_jxblog_category`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category_shop cs
ON(c.`id_jxblog_category` = cs.`id_jxblog_category`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category_group cg
ON(c.`id_jxblog_category` = cg.`id_jxblog_category`)
WHERE c.`active` = 1
AND c.`id_parent_category` = '.(int)$id_parent.'
AND cs.`id_shop` = '.(int)$id_shop.'
AND cg.`id_group` = '.(int)$id_group.'
AND cl.`id_lang` = '.(int)$id_lang.'
ORDER BY c.`position`
LIMIT '.(int)($page - 1) * $limit.','.(int)$limit
);
}
public static function getCategory($id_category, $id_lang, $id_shop, $id_group)
{
return Db::getInstance()->executeS(
'
SELECT c.*, cl.*
FROM '._DB_PREFIX_.'jxblog_category c
LEFT JOIN '._DB_PREFIX_.'jxblog_category_lang cl
ON(c.`id_jxblog_category` = cl.`id_jxblog_category`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category_shop cs
ON(c.`id_jxblog_category` = cs.`id_jxblog_category`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category_group cg
ON(c.`id_jxblog_category` = cg.`id_jxblog_category`)
WHERE c.id_jxblog_category = '.(int)$id_category.'
AND cs.`id_shop` = '.(int)$id_shop.'
AND cg.`id_group` = '.(int)$id_group.'
AND cl.`id_lang` = '.(int)$id_lang
);
}
public static function getSubCategories($id_category, $id_lang, $id_shop, $id_group)
{
return Db::getInstance()->executeS(
'
SELECT c.*, cl.*
FROM '._DB_PREFIX_.'jxblog_category c
LEFT JOIN '._DB_PREFIX_.'jxblog_category_lang cl
ON(c.`id_jxblog_category` = cl.`id_jxblog_category` AND cl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN '._DB_PREFIX_.'jxblog_category_shop cs
ON(c.`id_jxblog_category` = cs.`id_jxblog_category` AND cs.`id_shop` = '.(int)$id_shop.')
LEFT JOIN '._DB_PREFIX_.'jxblog_category_group cg
ON(c.`id_jxblog_category` = cg.`id_jxblog_category` AND cg.`id_group` = '.(int)$id_group.')
WHERE c.id_parent_category = '.(int)$id_category
);
}
public static function countFrontCategories($id_parent, $id_shop, $id_group)
{
$sql = 'SELECT count(*)
FROM '._DB_PREFIX_.'jxblog_category c
LEFT JOIN '._DB_PREFIX_.'jxblog_category_shop cs
ON(c.`id_jxblog_category` = cs.`id_jxblog_category`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category_group cg
ON(c.`id_jxblog_category` = cg.`id_jxblog_category`)
WHERE cs.`id_shop` = '.(int)$id_shop.'
AND cg.`id_group` = '.(int)$id_group.'
AND c.`id_parent_category` = '.(int)$id_parent;
return (int)Db::getInstance()->getValue($sql);
}
public static function getAllShopCategories($id_shop, $id_lang)
{
$sql = 'SELECT jc.`id_jxblog_category`, jcl.`name`, jcl.`id_lang`, jcs.`id_shop`
FROM '._DB_PREFIX_.'jxblog_category jc
LEFT JOIN '._DB_PREFIX_.'jxblog_category_shop jcs
ON(jc.`id_jxblog_category` = jcs.`id_jxblog_category`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category_lang jcl
ON(jc.`id_jxblog_category` = jcl.`id_jxblog_category` AND `id_lang` = '.(int)$id_lang.')
WHERE jc.`active` = 1
AND jcs.`id_shop` = '.(int)$id_shop;
return Db::getInstance()->executeS($sql);
}
public static function getChildrenCategories($id_category, $group = false, $active = false)
{
$sql = 'SELECT c.`id_jxblog_category` as id_category, cl.`name`, cl.`link_rewrite`, cs.`id_shop`
FROM '._DB_PREFIX_.'jxblog_category c
LEFT JOIN '._DB_PREFIX_.'jxblog_category_shop cs
ON(c.`id_jxblog_category` = cs.`id_jxblog_category`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category_lang cl
ON(c.`id_jxblog_category` = cl.`id_jxblog_category`)';
if ($group) {
$sql .= 'LEFT JOIN '._DB_PREFIX_.'jxblog_category_group cg
ON(c.`id_jxblog_category` = cg.`id_jxblog_category`)';
}
$sql .= ' WHERE c.`id_parent_category` = '.(int)$id_category.'
AND cs.`id_shop` = '.(int)Context::getContext()->shop->id;
if ($group) {
$sql .= ' AND cg.`id_group` = '.(int)$group;
}
if ($active) {
$sql .= ' AND c.`active` = 1';
}
return Db::getInstance()->executeS($sql);
}
public static function getCategoryShortInfo($id_category, $id_lang)
{
return Db::getInstance()->getRow(
'SELECT c.`id_jxblog_category`, c.`id_parent_category`, cl.`name`, cl.`link_rewrite`
FROM '._DB_PREFIX_.'jxblog_category c
JOIN '._DB_PREFIX_.'jxblog_category_lang cl
ON(c.`id_jxblog_category` = cl.`id_jxblog_category`)
WHERE c.`id_jxblog_category` = '.(int)$id_category.'
AND cl.`id_lang` = '.(int)$id_lang.'
AND c.`id_parent_category` != 0'
);
}
}

View File

@@ -0,0 +1,118 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class JXBlogImage extends ObjectModel
{
public $name;
public $width;
public $height;
public $category;
public $category_thumb;
public $post;
public $post_thumb;
public $user;
public static $definition = array(
'table' => 'jxblog_image',
'primary' => 'id_jxblog_image',
'multilang' => false,
'fields' => array(
'name' => array('type' => self::TYPE_STRING, 'validate' => 'isImageTypeName', 'required' => true, 'size' => 64),
'width' => array('type' => self::TYPE_INT, 'validate' => 'isImageSize', 'required' => true),
'height' => array('type' => self::TYPE_INT, 'validate' => 'isImageSize', 'required' => true),
'category' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'category_thumb' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'post' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'post_thumb' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'user' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool')
)
);
public function delete()
{
$result = true;
$module = new Jxblog();
if ($module->imagesAutoRegenerate) {
$imageManager = new JXBlogImageManager($module);
$result &= $imageManager->removeImageTypeImages($this->id);
}
$result &= parent::delete();
Hook::exec('actionJxblogImageAfterDelete', array('id_jxblog_image' => $this->id));
return $result;
}
/**
* Check if such image type is already exists. Usage of name more than once is forbidden
*
* @param $name
* @param bool $id
*
* @return false|null|string
*/
public static function checkIfNameExists($name, $id = false)
{
$condition = '';
if ($id) {
$condition = ' AND `id_jxblog_image` != '.$id;
}
return Db::getInstance()->getValue('SELECT * FROM '._DB_PREFIX_.'jxblog_image WHERE `name` = "'.pSQL($name).'"'.$condition);
}
/**
* Get all image types related to images category
*
* @param bool $type
* @param bool $name
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public static function getImageTypesByCategory($type = false, $name = false)
{
$condition = '';
if ($type && $type != 'default') {
$condition = ' WHERE `'.$type.'` = 1';
}
if ($name && $type == 'default') {
$condition .= ' WHERE `name` = "'.pSQL($name).'"';
} elseif ($name) {
$condition .= ' AND `name` = "'.pSQL($name).'"';
}
return Db::getInstance()->executeS('SELECT `name`, `width`, `height` FROM '._DB_PREFIX_.'jxblog_image'.$condition);
}
/**
* Get information about image type such as width/height etc.
*
* @param $type
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public static function getImageTypeInfo($type)
{
return Db::getInstance()->executeS('SELECT `name`, `width`, `height` FROM '._DB_PREFIX_.'jxblog_image WHERE `name` ="'.pSQL($type).'"');
}
}

View File

@@ -0,0 +1,336 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class JXBlogImageManager
{
public $module;
public $languages;
public function __construct($module = false)
{
$this->module = $module;
$this->languages = Language::getLanguages(false);
}
/**
* Upload an image and generate all related images from this one if auto regeneration option is enabled
*
* @param $id post/category to which an image is related to
* @param $file an image file information $_FILE
* @param $type typo of image category/post/user
*
* @return bool|mixed|string
*/
public function uploadImage($id, $file, $type)
{
if (isset($file['name']) && isset($file['tmp_name']) && !Tools::isEmpty($file['tmp_name'])) {
if ($error = ImageManager::validateUpload($file, Tools::getMaxUploadSize(), array('jpg'))) {
return $error;
} else {
$ext = Tools::substr($file['name'], strrpos($file['name'], '.') + 1);
$file_name = $id.'.'.$ext;
if ($type== 'default') {
$path = $this->module->modulePath.'img/';
} else {
$path = $this->module->modulePath.'img/'.$this->module->imageTypes[$type][0];
}
if (!is_dir($path)) {
mkdir($path, 0777, true);
}
if (!move_uploaded_file($file['tmp_name'], $path.$file_name)) {
return Context::getContext()->getTranslator()->trans('Error while uploading image.', array($file['error']), 'Modules.JXBlog.Admin');
}
// if auto regeneration option is enabled generate all image's types related to this content type
if ($this->module->imagesAutoRegenerate && !$this->regenerateTypeImages($type, $id)) {
return Context::getContext()->getTranslator()->trans('Error while generating images.', array($file['error']), 'Modules.JXBlog.Admin');
}
}
}
return false;
}
/**
* Remove the main image and all related images by id and content type
*
* @param $id content element
* @param $type content type (category, category_thumb, post etc.)
*
* @return bool
*/
public function removeImages($id, $type)
{
// remove main image if exists
if (file_exists($this->module->modulePath.'img/'.$this->module->imageTypes[$type][0].$id.'.jpg')) {
unlink($this->module->modulePath.'img/'.$this->module->imageTypes[$type][0].$id.'.jpg');
}
$categoryImages = JXBlogImage::getImageTypesByCategory($type);
// remove related images if exists
if ($categoryImages) {
foreach ($categoryImages as $categoryImage) {
if (file_exists($this->module->modulePath.'img/'.$this->module->imageTypes[$type][0].$id.'-'.$categoryImage['name'].'.jpg')) {
unlink($this->module->modulePath.'img/'.$this->module->imageTypes[$type][0].$id.'-'.$categoryImage['name'].'.jpg');
}
}
}
return true;
}
/**
* Regenerate type images.
* If only a content type is defined, regenerate all images(all types related to a content type) for all content's items(all categories/posts etc.).
* If a content type and an item id are defined, regenerate all images(all types related to a content type) but only for this item (category/post etc.)
* If all parameters are defined, regenerate only this image type for only this item (category/post etc.)
* @param string $type type of a content
* @param bool $id an item id from content (category/post etc.)
* @param bool $image_type an image type (category_small/post_small etc.)
*
* @return bool
*/
public function regenerateTypeImages($type = 'category', $id = false, $image_type = false)
{
$result = array();
// if image type isn't predefined find all related types in database else use the predefined image type
// check if any image type exists for this kind of data, if not return success
if (!$imageTypes = JXBlogImage::getImageTypesByCategory($type, $image_type)) {
return true;
}
// select all available items from db to which images can be related to
$data = $this->getItemsToRegenerate($type, $id);
if ($data) {
foreach ($data as $item) {
if (file_exists($this->module->modulePath.'img/'.$this->module->imageTypes[$type][0].$item['id'].'.jpg')) {
$result[$item['id']]['source'] = $this->module->modulePath.'img/'.$this->module->imageTypes[$type][0].$item['id'].'.jpg';
$result[$item['id']]['name'] = $item['id'];
$result[$item['id']]['path'] = $this->module->modulePath.'img/'.$this->module->imageTypes[$type][0];
$result[$item['id']]['file'] = $item['id'].'.jpg';
}
}
}
// add languages images if it is the regeneration for all categories images
if (!$id) {
$result = array_merge($this->getLanguagesImages($this->module->modulePath.'img/'.$this->module->imageTypes[$type][0]), $result);
}
if (!$result) {
return true;
}
if (!$this->regenerateImages($imageTypes, $result)) {
return false;
}
return true;
}
/**
* Select all available items from db to which images can be related to, or return id if it is defined
* @param $type
* @param bool $id
*
* @return array|false|mysqli_result|null|PDOStatement|resource
*/
public function getItemsToRegenerate($type, $id = false)
{
if (!$id) {
if ($type == 'category' || $type == 'category_thumb') {
$data = JXBlogCategory::getAllCategories();
} elseif ($type == 'post' || $type == 'post_thumb') {
$data = JXBlogPost::getAllPosts();
} else {
$data = array();
}
} else {
$data[]['id'] = $id;
}
return $data;
}
/**
* Get default images for each language in case if elements don't have their own images these will be display
* @param $path
*
* @return array
*/
public function getLanguagesImages($path)
{
$result = array();
foreach ($this->languages as $language) {
if (file_exists($path.$language['iso_code'].'.jpg')) {
$result[$language['iso_code']]['source'] = $path.$language['iso_code'].'.jpg';
$result[$language['iso_code']]['name'] = $language['iso_code'];
$result[$language['iso_code']]['path'] = $path;
$result[$language['iso_code']]['file'] = $language['iso_code'].'.jpg';
}
}
return $result;
}
/**
* Regenerate images by types list and images' paths list
* @param $types list of images' types
* @param $images list of paths to images
*
* @return bool
*/
public function regenerateImages($types, $images)
{
$result = true;
foreach ($types as $type) {
foreach ($images as $source) {
$result &= ImageManager::resize($source['source'], $source['path'].$source['name'].'-'.$type['name'].'.jpg', $type['width'], $type['height'], 'jpg', true);
}
}
return $result;
}
/**
* Remove all images related the to current image type if the type is removing,
* or remove only that images which are related to the type category
* if these images no more related to this type
*
* @param $id_jxblog_image id of the image type
* @param bool $image_category name of the content type
*
* @return bool
*/
public function removeImageTypeImages($id_jxblog_image, $image_category = false)
{
$imageType = new JXBlogImage((int)$id_jxblog_image);
$data = array();
if (!$image_category) {
foreach (array_keys($this->module->imageTypes) as $type) {
if ($type == 'default' || ($type != 'default' && $imageType->$type)) {
$data[$type] = $this->getItemsToRegenerate($type);
}
}
} else {
$data[$image_category] = $this->getItemsToRegenerate($image_category);
}
if (!$data) {
return true;
}
if (!$imagesToRemove = $this->buildImagesListToRemove($data, $imageType->name)) {
return true;
}
return $this->removeImagesByList($imagesToRemove);
}
/**
* Build full list of images which are suitable for removing
*
* @param $list list of all content which is related to the image type
* @param $typeName name of the image type
*
* @return array
*/
public function buildImagesListToRemove($list, $typeName)
{
$result = array();
foreach ($list as $type => $items) {
// check and add image if it exists for different content
foreach ($items as $item) {
if (file_exists($this->module->modulePath.'img/'.$this->module->imageTypes[$type][0].$item['id'].'-'.$typeName.'.jpg')) {
$result[] = $this->module->modulePath.'img/'.$this->module->imageTypes[$type][0].$item['id'].'-'.$typeName.'.jpg';
}
}
// check and add image if it exists for different languages
foreach ($this->languages as $language) {
if (file_exists($this->module->modulePath.'img/'.$this->module->imageTypes[$type][0].$language['iso_code'].'-'.$typeName.'.jpg')) {
$result[] = $this->module->modulePath.'img/'.$this->module->imageTypes[$type][0].$language['iso_code'].'-'.$typeName.'.jpg';
}
}
}
return $result;
}
/**
* Remove images by paths list
* @param $list
*
* @return bool
*/
public function removeImagesByList($list)
{
if (!is_array($list)) {
return false;
}
$result = true;
foreach ($list as $item) {
$result &= unlink($item);
}
return $result;
}
public static function getImage($type, $id, $imageType = 'default')
{
$module = new JXBlog();
if (!$type || !isset($module->imageTypes[$type])) {
return false;
}
if (!$id) {
$id = Context::getContext()->language->iso_code;
}
$path = $module->modulePath.'img/';
$lnk = $module->_link.'img/';
if (file_exists($path.$module->imageTypes[$type][0].$id.'-'.$imageType.'.jpg')) {
return $lnk.$module->imageTypes[$type][0].$id.'-'.$imageType.'.jpg';
}
if (file_exists($path.$module->imageTypes[$type][0].$id.'.jpg')) {
return $lnk.$module->imageTypes[$type][0].$id.'.jpg';
}
if (file_exists($path.$module->imageTypes[$type][0].Context::getContext()->language->iso_code.'-'.$imageType.'.jpg')) {
return $lnk.$module->imageTypes[$type][0].Context::getContext()->language->iso_code.'-'.$imageType.'.jpg';
}
if (file_exists($path.$module->imageTypes[$type][0].$module->defaultLanguage->iso_code.'-'.$imageType.'.jpg')) {
return $lnk.$module->imageTypes[$type][0].$module->defaultLanguage->iso_code.'-'.$imageType.'.jpg';
}
if (file_exists($path.$module->imageTypes[$type][0].Context::getContext()->language->iso_code.'.jpg')) {
return $lnk.$module->imageTypes[$type][0].Context::getContext()->language->iso_code.'.jpg';
}
if (file_exists($path.Context::getContext()->language->iso_code.'.jpg')) {
return $lnk.Context::getContext()->language->iso_code.'.jpg';
}
if (file_exists($path.$module->defaultLanguage->iso_code.'.jpg')) {
return $lnk.$module->defaultLanguage->iso_code.'.jpg';
}
return false;
}
}

View File

@@ -0,0 +1,716 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class JXBlogPost extends ObjectModel
{
protected $module;
protected $imageManager;
protected $context;
public $id_jxblog_category_default;
public $author;
public $views;
public $active;
public $date_add;
public $date_upd;
public $date_start;
public $name;
public $link_rewrite;
public $description;
public $short_description;
public $meta_keyword;
public $meta_description;
public static $definition = array(
'table' => 'jxblog_post',
'primary' => 'id_jxblog_post',
'multilang' => true,
'fields' => array(
'id_jxblog_category_default' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
'author' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
'views' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
'active' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
'date_upd' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
'date_start' => array('type' => self::TYPE_DATE, 'validate' => 'isDateFormat'),
// language fields
'name' => array('type' => self::TYPE_STRING, 'validate' => 'isCatalogName', 'lang' => true, 'required' => true, 'size' => 64),
'link_rewrite' => array('type' => self::TYPE_STRING, 'validate' => 'isLinkRewrite', 'lang' => true, 'required' => true, 'size' => 64),
'description' => array('type' => self::TYPE_HTML, 'validate' => 'isCleanHtml', 'lang' => true),
'short_description' => array('type' => self::TYPE_HTML, 'validate' => 'isCleanHtml', 'lang' => true),
'meta_keyword' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isString'),
'meta_description' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isString')
)
);
public function __construct($id = null, $lang = null, $shop = null)
{
$this->module = new Jxblog();
$this->context = Context::getContext();
$this->imageManager = new JXBlogImageManager($this->module);
parent::__construct($id, $lang, $shop);
}
public function add($auto_date = true, $null_values = false)
{
Hook::exec('actionJxblogPostBeforeAdd', array('id_jxblog_post' => $this->id));
$result = true;
if (!Tools::getValue('date_start')) {
$this->date_start = date('Y-m-d H:i:s');
}
$this->author = $this->context->employee->id;
$result &= parent::add($auto_date, $null_values);
$result &= $this->updatePostImages();
$result &= $this->associatePostToCategories();
$result &= $this->associateTagsToPost();
Hook::exec('actionJxblogPostAfterAdd', array('id_jxblog_post' => $this->id));
return $result;
}
public function update($null_values = false)
{
Hook::exec('actionJxblogPostBeforeUpdate', array('id_jxblog_post' => $this->id));
// remove tmp mini image for posts in admin listing
@unlink(_PS_TMP_IMG_DIR_ . 'jxblog_post_mini_' .(int)$this->id.'_'.Context::getContext()->shop->id.'.jpg');
$result = true;
$result &= parent::update($null_values);
// avoid data removing during status updating within ajax
if (!Tools::getIsset('action') || Tools::getValue('action') != 'statusjxblog_post') {
$result &= $this->updatePostImages();
$result &= $this->associatePostToCategories();
$result &= $this->associateTagsToPost();
}
Hook::exec('actionJxblogPostAfterUpdate', array('id_jxblog_post' => $this->id));
return $result;
}
public function delete()
{
Hook::exec('actionJxblogPostBeforeDelete', array('id_jxblog_post' => $this->id));
$result = true;
$result &= parent::delete();
$result &= $this->disassociatePostToCategories();
$result &= $this->disassociateTagsToPost();
$result &= $this->imageManager->removeImages($this->id, 'post');
$result &= $this->imageManager->removeImages($this->id, 'post_thumb');
Hook::exec('actionJxblogPostAfterDelete', array('id_jxblog_post' => $this->id));
return $result;
}
public function getPostsByDefaultCategory($id_jxblog_category)
{
return Db::getInstance()->executeS('SELECT `id_jxblog_post` FROM '._DB_PREFIX_.'jxblog_post WHERE `id_jxblog_category_default` = '.(int)$id_jxblog_category);
}
/**
* Associate the product to all related categories
*
* @return bool
* @throws PrestaShopDatabaseException
*/
private function associatePostToCategories()
{
if (!$this->disassociatePostToCategories()) {
return false;
}
$categories = Tools::getValue('jxcategoryBox');
// add default category to the categories list
if (!Db::getInstance()->insert('jxblog_post_category', array('id_jxblog_post' => (int)$this->id, 'id_jxblog_category' => (int)$this->id_jxblog_category_default))) {
return false;
}
foreach ($categories as $category) {
// verify if current category isn't the default category. Skip if it is so to avoid a duplicating issue
if ((int)$category != $this->id_jxblog_category_default) {
if (!Db::getInstance()->insert(
'jxblog_post_category',
array(
'id_jxblog_post' => (int)$this->id,
'id_jxblog_category' => (int)$category
))
) {
return false;
}
}
}
return true;
}
public function resetDefaultCategory($id_jxblog_category, $new_category_id = 1)
{
return Db::getInstance()->update('jxblog_post', array('id_jxblog_category_default' => (int)$new_category_id), '`id_jxblog_category_default` = '.(int)$id_jxblog_category);
}
private function disassociatePostToCategories()
{
if (!Db::getInstance()->delete('jxblog_post_category', '`id_jxblog_post` = '.(int)$this->id)) {
return false;
}
return true;
}
/**
* Get all categories to which the product is associated
*
* @return array
* @throws PrestaShopDatabaseException
*/
public function getAssociatedCategories()
{
$result = array();
$categories = Db::getInstance()->executeS('SELECT `id_jxblog_category` FROM '._DB_PREFIX_.'jxblog_post_category WHERE `id_jxblog_post` = '.(int)$this->id);
if (!$categories) {
return array();
} else {
foreach ($categories as $category) {
array_push($result, $category['id_jxblog_category']);
}
}
return $result;
}
private function associateTagsToPost()
{
if (!$this->disassociateTagsToPost()) {
return false;
}
foreach ($this->module->languages as $language) {
$language_tags = Tools::getValue('tags_'.$language['id_lang']);
if ($language_tags) {
$tags = explode(',', $language_tags);
foreach ($tags as $tag) {
if (!$id_tag = JXBlogTag::checkTagExistence($language['id_lang'], $tag)) {
$newTag = new JXBlogTag();
$newTag->id_lang = $language['id_lang'];
$newTag->tag = $tag;
if (!$newTag->add()) {
return false;
} else {
Db::getInstance()->insert('jxblog_tag_post', array('id_jxblog_tag' => (int)$newTag->id, 'id_jxblog_post' => (int)$this->id));
}
} else {
Db::getInstance()->insert('jxblog_tag_post', array('id_jxblog_tag' => (int)$id_tag, 'id_jxblog_post' => (int)$this->id));
}
}
}
}
return true;
}
private function disassociateTagsToPost()
{
if (!Db::getInstance()->delete('jxblog_tag_post', '`id_jxblog_post` = '.(int)$this->id)) {
return false;
}
return true;
}
public function getAdminPostTags()
{
$rawTags = JXBlogTag::getPostTags($this->id);
if (!$rawTags) {
return false;
}
$result = array();
foreach (Language::getLanguages(false) as $language) {
$result[$language['id_lang']] = array();
foreach ($rawTags as $tag) {
if ($tag['id_lang'] == $language['id_lang']) {
$result[$language['id_lang']][] = $tag['tag'];
}
}
$result[$language['id_lang']] = implode(',', $result[$language['id_lang']]);
}
return $result;
}
/**
* Live search for the post to use in autocomplete
*
* @param $name
* @param $id_lang
* @param $limit
* @param array $excluded
*
* @return array|bool
* @throws PrestaShopDatabaseException
*/
public static function searchPostsLive($name, $id_lang, $limit, $excluded = array())
{
$result = array();
$sql = 'SELECT p.`id_jxblog_post` as `id`, pl.`name` as `name`
FROM '._DB_PREFIX_.'jxblog_post p
LEFT JOIN '._DB_PREFIX_.'jxblog_post_lang pl
ON(pl.`id_jxblog_post`=p.`id_jxblog_post`)
WHERE pl.`id_lang` = '.(int)$id_lang.'
AND pl.`name` LIKE "%'.pSQL($name).'%"';
if ($excluded) {
$sql .= ' AND p.`id_jxblog_post` NOT IN ('.implode(',', $excluded).')';
}
$sql .= ' LIMIT '.(int)$limit;
if (!$res = Db::getInstance()->executeS($sql)) {
return false;
}
foreach ($res as $item) {
$result[] = $item['name'].'|'.$item['id'];
}
return $result;
}
/**
* Update post image if they were changed
*
* @return bool
* @throws PrestaShopException
*/
private function updatePostImages()
{
if (!Tools::isEmpty(Tools::getValue('image')) && Tools::getValue('image')) {
if ($error = $this->imageManager->uploadImage($this->id, $_FILES['image'], 'post')) {
die(Tools::displayError($error));
}
}
if (!Tools::isEmpty(Tools::getValue('thumbnail')) && Tools::getValue('thumbnail')) {
if ($error = $this->imageManager->uploadImage($this->id, $_FILES['thumbnail'], 'post_thumb')) {
die(Tools::displayError($error));
}
}
return true;
}
/**
* Get full list of posts with access information
*
* @param bool $idLang
* @param bool $idShop
* @param bool $idGroup
* @param bool $page
* @param bool $itemPerPage
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public static function getAllPosts($idLang = false, $idShop = false, $idGroup = false, $page = false, $itemPerPage = false)
{
if ($idLang && $page && $itemPerPage) {
return Db::getInstance()->executeS(
'SELECT DISTINCT p.*, pl.*
FROM '._DB_PREFIX_.'jxblog_post p
LEFT JOIN '._DB_PREFIX_.'jxblog_post_lang pl
ON(p.`id_jxblog_post` = pl.`id_jxblog_post`)
LEFT JOIN '._DB_PREFIX_.'jxblog_post_category pc
ON(p.`id_jxblog_post` = pc.`id_jxblog_post`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category c
ON(pc.`id_jxblog_category` = c.`id_jxblog_category`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category_shop ps
ON(pc.`id_jxblog_category` = ps.`id_jxblog_category`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category_group pg
ON(pc.`id_jxblog_category` = pg.`id_jxblog_category`)
WHERE p.`date_start` <= NOW()
AND pl.`id_lang` = '.(int)$idLang.'
AND ps.`id_shop` = '.(int)$idShop.'
AND pg.`id_group` = '.(int)$idGroup.'
AND p.`active` = 1
AND c.`active` = 1
LIMIT '.(int)($page - 1)*$itemPerPage.','.(int)$itemPerPage
);
}
return Db::getInstance()->executeS('SELECT `id_jxblog_post` AS `id` FROM '._DB_PREFIX_.'jxblog_post');
}
public static function countAllPosts($idShop, $idGroup)
{
$sql = 'SELECT DISTINCT count(*)
FROM '._DB_PREFIX_.'jxblog_post p
LEFT JOIN '._DB_PREFIX_.'jxblog_post_category pc
ON(p.`id_jxblog_post` = pc.`id_jxblog_post`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category c
ON(pc.`id_jxblog_category` = c.`id_jxblog_category`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category_shop ps
ON(pc.`id_jxblog_category` = ps.`id_jxblog_category`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category_group pg
ON(pc.`id_jxblog_category` = pg.`id_jxblog_category`)
WHERE p.`date_start` <= NOW()
AND ps.`id_shop` = '.(int)$idShop.'
AND pg.`id_group` = '.(int)$idGroup.'
AND p.`active` = 1
AND c.`active` = 1';
return Db::getInstance()->getValue($sql);
}
/**
* Get all post related to the certain category
*
* @param $id_category
* @param $id_lang
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public static function getAllPostsByCategory($id_category, $id_lang)
{
$sql = 'SELECT p.*, pl.*
FROM '._DB_PREFIX_.'jxblog_post p
LEFT JOIN '._DB_PREFIX_.'jxblog_post_lang pl
ON(p.`id_jxblog_post` = pl.`id_jxblog_post` AND pl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN '._DB_PREFIX_.'jxblog_post_category pc
ON(p.`id_jxblog_post` = pc.`id_jxblog_post`)
WHERE p.`date_start` <= NOW()
AND pc.`id_jxblog_category` = '.(int)$id_category.'
AND p.`active` = 1';
return Db::getInstance()->executeS($sql);
}
/**
* Get post related to the certain category for listing
*
* @param $id_category
* @param $id_lang
* @param int $start
* @param int $limit
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public static function getPostsByCategory($id_category, $id_lang, $start = 0, $limit = 10)
{
$sql = 'SELECT p.*, pl.*, CONCAT(e.`firstname`, " ", e.`lastname`) as `author`
FROM '._DB_PREFIX_.'jxblog_post p
LEFT JOIN '._DB_PREFIX_.'jxblog_post_lang pl
ON(p.`id_jxblog_post` = pl.`id_jxblog_post` AND pl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN '._DB_PREFIX_.'jxblog_post_category pc
ON(p.`id_jxblog_post` = pc.`id_jxblog_post`)
LEFT JOIN '._DB_PREFIX_.'employee e
ON(p.`author` = e.`id_employee`)
WHERE p.`date_start` <= NOW()
AND pc.`id_jxblog_category` = '.(int)$id_category.'
AND p.`active` = 1
LIMIT '.(int)($start - 1)*$limit.','.(int)$limit;
return Db::getInstance()->executeS($sql);
}
/**
* Count all post related to category
*
* @param $id_category
*
* @return false|null|string
*/
public static function countPostsByCategory($id_category)
{
$sql = 'SELECT count(*)
FROM '._DB_PREFIX_.'jxblog_post p
LEFT JOIN '._DB_PREFIX_.'jxblog_post_category pc
ON(p.`id_jxblog_post` = pc.`id_jxblog_post`)
WHERE p.`date_start` <= NOW()
AND pc.`id_jxblog_category` = '.(int)$id_category.'
AND p.`active` = 1';
return Db::getInstance()->getValue($sql);
}
/**
* Check if current user has an access to the post
*
* @param $id_jxblog_post
* @param $id_shop
* @param $id_user_group
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
private static function checkAccess($id_jxblog_post, $id_shop, $id_user_group)
{
$sql = 'SELECT pc.`id_jxblog_category`
FROM '._DB_PREFIX_.'jxblog_post_category pc
LEFT JOIN '._DB_PREFIX_.'jxblog_category_shop cs
ON(pc.`id_jxblog_category` = cs.`id_jxblog_category`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category_group cg
ON(pc.`id_jxblog_category` = cg.`id_jxblog_category`)
WHERE pc.`id_jxblog_post` = '.(int)$id_jxblog_post.'
AND cs.`id_shop` = '.(int)$id_shop.'
AND cg.`id_group` = '.(int)$id_user_group;
return Db::getInstance()->executeS($sql);
}
/**
* Get the post information
*
* @param $id_jxblog_post
* @param $id_lang
* @param $id_shop
* @param $id_user_group
*
* @return array|bool|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public static function getPost($id_jxblog_post, $id_lang, $id_shop, $id_user_group)
{
if (!self::checkAccess($id_jxblog_post, $id_shop, $id_user_group)) {
return false;
}
$sql = 'SELECT p.*, pl.*, p.`author` as `id_author`, CONCAT(e.`firstname`," ", e.`lastname`) as `author`
FROM '._DB_PREFIX_.'jxblog_post p
LEFT JOIN '._DB_PREFIX_.'jxblog_post_lang pl
ON(p.`id_jxblog_post` = pl.id_jxblog_post AND pl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN '._DB_PREFIX_.'employee e
ON(p.`author` = e.`id_employee`)
WHERE p.`id_jxblog_post` = '.(int)$id_jxblog_post.'
AND p.`active` = 1';
return Db::getInstance()->executeS($sql);
}
/**
* Get the post tags
*
* @param $id_jxblog_post
* @param $id_lang
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public static function getPostTags($id_jxblog_post, $id_lang)
{
return Db::getInstance()->executeS('
SELECT t.*
FROM '._DB_PREFIX_.'jxblog_tag t
LEFT JOIN '._DB_PREFIX_.'jxblog_tag_post tp
ON(tp.`id_jxblog_tag`=t.`id_jxblog_tag`)
WHERE tp.`id_jxblog_post` = '.(int)$id_jxblog_post.'
AND t.`id_lang` = '.(int)$id_lang);
}
/**
* Get post by tag for listing by tag
*
* @param $id_tag
* @param $id_lang
* @param int $start
* @param int $limit
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public static function getPostsByTag($id_tag, $id_lang, $start = 0, $limit = 10)
{
$sql = 'SELECT p.*, pl.*, CONCAT(e.`firstname`, " ", e.`lastname`) as `author`
FROM '._DB_PREFIX_.'jxblog_post p
LEFT JOIN '._DB_PREFIX_.'jxblog_post_lang pl
ON(p.`id_jxblog_post` = pl.`id_jxblog_post` AND pl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN '._DB_PREFIX_.'jxblog_tag_post ptp
ON(p.`id_jxblog_post` = ptp.`id_jxblog_post`)
LEFT JOIN '._DB_PREFIX_.'employee e
ON(p.`author` = e.`id_employee`)
WHERE p.`date_start` <= NOW()
AND ptp.`id_jxblog_tag` = '.(int)$id_tag.'
AND p.`active` = 1
LIMIT '.(int)($start - 1)*$limit.','.(int)$limit;
return Db::getInstance()->executeS($sql);
}
/**
* Count all posts related to the tag
* @param $id_tag
*
* @return false|null|string
*/
public static function countPostsByTag($id_tag)
{
$sql = 'SELECT count(*)
FROM '._DB_PREFIX_.'jxblog_post p
LEFT JOIN '._DB_PREFIX_.'jxblog_tag_post ptp
ON(p.`id_jxblog_post` = ptp.`id_jxblog_post`)
WHERE p.`date_start` <= NOW()
AND ptp.`id_jxblog_tag` = '.(int)$id_tag.'
AND p.`active` = 1';
return Db::getInstance()->getValue($sql);
}
/**
* Get posts by author
* @param $id_author
* @param int $start
* @param int $limit
* @param $id_lang
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public static function getPostsByAuthor($id_author, $id_lang, $start = 0, $limit = 10)
{
$sql = 'SELECT p.*, pl.*, CONCAT(e.`firstname`, " ", e.`lastname`) as `author`
FROM '._DB_PREFIX_.'jxblog_post p
LEFT JOIN '._DB_PREFIX_.'jxblog_post_lang pl
ON(p.`id_jxblog_post` = pl.`id_jxblog_post` AND pl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN '._DB_PREFIX_.'employee e
ON(p.`author` = e.`id_employee`)
WHERE p.`date_start` <= NOW()
AND p.`author` = '.(int)$id_author.'
AND p.`active` = 1
LIMIT '.(int)($start - 1)*$limit.','.(int)$limit;
return Db::getInstance()->executeS($sql);
}
/**
* Count all author's posts
*
* @param $id_author
*
* @return false|null|string
*/
public static function countPostsByAuthor($id_author)
{
$sql = 'SELECT count(*)
FROM '._DB_PREFIX_.'jxblog_post p
WHERE p.`date_start` <= NOW()
AND p.`author` = '.(int)$id_author.'
AND p.`active` = 1';
return Db::getInstance()->getValue($sql);
}
/**
* Update number of post views
*
* @param $id_post
*
* @return bool
*/
public static function postViewed($id_post)
{
$sql = 'UPDATE '._DB_PREFIX_.'jxblog_post SET `views` = (views+1) where `id_jxblog_post` = '.(int)$id_post;
return Db::getInstance()->execute($sql);
}
public static function getAllShopPosts($id_shop, $id_lang)
{
$sql = 'SELECT DISTINCT jp.`id_jxblog_post`, jpl.`name`
FROM '._DB_PREFIX_.'jxblog_post jp
LEFT JOIN '._DB_PREFIX_.'jxblog_post_lang jpl
ON(jp.`id_jxblog_post`=jpl.`id_jxblog_post` AND jpl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN '._DB_PREFIX_.'jxblog_post_category jpc
ON(jp.`id_jxblog_post` = jpc.`id_jxblog_post`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category jc
ON(jpc.`id_jxblog_category` = jc.`id_jxblog_category`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category_shop jcs
ON(jcs.`id_jxblog_category` = jc.`id_jxblog_category`)
WHERE jp.`active` = 1
AND jcs.`id_shop` = '.(int)$id_shop.'
AND jc.`active` = 1';
return Db::getInstance()->executeS($sql);
}
/**
* Search for products by defined parameters. Check all accesses before showing
* to prevent displaying products which are in private categories or in other stores
*
* @param $query
* @param $id_category
* @param $id_lang
* @param $id_shop
* @param $id_customer_group
* @param int $start
* @param int $limit
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public static function search($query, $id_category, $id_lang, $id_shop, $id_customer_group, $start = 0, $limit = 10)
{
$sql = 'SELECT DISTINCT p.*, pl.*
FROM '._DB_PREFIX_.'jxblog_post p
LEFT JOIN '._DB_PREFIX_.'jxblog_post_lang pl
ON(p.`id_jxblog_post` = pl.`id_jxblog_post` AND pl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN '._DB_PREFIX_.'jxblog_post_category pc
ON(p.`id_jxblog_post` = pc.`id_jxblog_post`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category_group cg
ON(pc.`id_jxblog_category` = cg.`id_jxblog_category`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category_shop cs
ON(pc.`id_jxblog_category` = cs.`id_jxblog_category`)
WHERE (pl.`name` LIKE "%'.pSQL($query).'%" OR pl.short_description LIKE "%'.pSQL($query).'%" OR pl.description LIKE "%'.pSQL($query).'%")
AND p.`active` = 1';
// add condition if category is defined
if ($id_category > 2) {
$sql .= ' AND pc.`id_jxblog_category` = '.(int)$id_category;
}
$sql .= ' AND cg.`id_group` = '.(int)$id_customer_group.'
AND cs.`id_shop` = '.(int)$id_shop.'
LIMIT '.(int)($start - 1)*$limit.','.(int)$limit;
return Db::getInstance()->executeS($sql);
}
public static function countPostsBySearch($query, $id_category, $id_lang, $id_shop, $id_customer_group)
{
$sql = 'SELECT COUNT(DISTINCT p.id_jxblog_post) AS Count
FROM '._DB_PREFIX_.'jxblog_post p
LEFT JOIN '._DB_PREFIX_.'jxblog_post_lang pl
ON(p.`id_jxblog_post` = pl.`id_jxblog_post` AND pl.`id_lang` = '.(int)$id_lang.')
LEFT JOIN '._DB_PREFIX_.'jxblog_post_category pc
ON(p.`id_jxblog_post` = pc.`id_jxblog_post`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category_group cg
ON(pc.`id_jxblog_category` = cg.`id_jxblog_category`)
LEFT JOIN '._DB_PREFIX_.'jxblog_category_shop cs
ON(pc.`id_jxblog_category` = cs.`id_jxblog_category`)
WHERE (pl.`name` LIKE "%'.pSQL($query).'%" OR pl.short_description LIKE "%'.pSQL($query).'%" OR pl.description LIKE "%'.pSQL($query).'%")
AND p.`active` = 1';
// add condition if category is defined
if ($id_category > 2) {
$sql .= ' AND pc.`id_jxblog_category` = '.(int)$id_category;
}
$sql .= ' AND cg.`id_group` = '.(int)$id_customer_group.'
AND cs.`id_shop` = '.(int)$id_shop;
return Db::getInstance()->getValue($sql);
}
}

View File

@@ -0,0 +1,72 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class JXBlogTag extends ObjectModel
{
public $id_lang;
public $tag;
public static $definition = array(
'table' => 'jxblog_tag',
'primary' => 'id_jxblog_tag',
'multilang' => false,
'fields' => array(
'id_lang' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
'tag' => array('type' => self::TYPE_STRING, 'validate' => 'isCatalogName', 'required' => true, 'size' => 64)
)
);
/**
* Check if tag is already exists to prevent duplicating
*
* @param $id_lang
* @param $tag
*
* @return false|null|string
*/
public static function checkTagExistence($id_lang, $tag)
{
return Db::getInstance()->getValue('
SELECT `id_jxblog_tag`
FROM '._DB_PREFIX_.'jxblog_tag
WHERE `tag` = "'.pSql($tag).'"
AND `id_lang` = '.(int)$id_lang);
}
/**
* Get all post tags
*
* @param $id_jxblog_post
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public static function getPostTags($id_jxblog_post)
{
return Db::getInstance()->executeS('
SELECT t.*
FROM '._DB_PREFIX_.'jxblog_tag t
LEFT JOIN '._DB_PREFIX_.'jxblog_tag_post tp
ON(tp.`id_jxblog_tag`=t.`id_jxblog_tag`)
WHERE tp.`id_jxblog_post` = '.(int)$id_jxblog_post);
}
}

13
modules/jxblog/config.xml Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>jxblog</name>
<displayName><![CDATA[JX Blog]]></displayName>
<version><![CDATA[1.1.2]]></version>
<description><![CDATA[The best blog-extension for Prestashop platform.]]></description>
<author><![CDATA[Zemez (Alexander Grosul)]]></author>
<tab><![CDATA[content_management]]></tab>
<confirmUninstall><![CDATA[Are you sure that you want to delete the module? All related data will be deleted forever!]]></confirmUninstall>
<is_configurable>0</is_configurable>
<need_instance>1</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>jxblog</name>
<displayName><![CDATA[JX Blog]]></displayName>
<version><![CDATA[1.1.2]]></version>
<description><![CDATA[The best blog-extension for Prestashop platform.]]></description>
<author><![CDATA[Zemez (Alexander Grosul)]]></author>
<tab><![CDATA[content_management]]></tab>
<confirmUninstall><![CDATA[Are you sure that you want to delete the module? All related data will be deleted forever!]]></confirmUninstall>
<is_configurable>0</is_configurable>
<need_instance>1</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,4 @@
drwxr-xr-x 4 30094 users 4 Oct 6 10:16 .
drwxr-xr-x 9 30094 users 16 Oct 6 10:16 ..
drwxr-xr-x 2 30094 users 6 Oct 6 10:16 admin
drwxr-xr-x 2 30094 users 9 Oct 6 10:16 front

View File

@@ -0,0 +1,6 @@
drwxr-xr-x 2 30094 users 6 Oct 6 10:16 .
drwxr-xr-x 4 30094 users 4 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 33073 Aug 31 2021 AdminJXBlogCategories.php
-rw-r--r-- 1 30094 users 26016 Aug 31 2021 AdminJXBlogImages.php
-rw-r--r-- 1 30094 users 3927 Aug 31 2021 AdminJXBlogMainSettings.php
-rw-r--r-- 1 30094 users 16150 Aug 31 2021 AdminJXBlogPosts.php

View File

@@ -0,0 +1,723 @@
<?php
/**
* 2017-2019 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2019 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class AdminJXBlogCategoriesController extends ModuleAdminController
{
public $_category = null;
protected $position_identifier = 'id_jxblog_category_to_move';
public $imageManager;
public $breadCrumbs = array();
protected $helper;
public function __construct()
{
$this->table = 'jxblog_category';
$this->list_id = $this->table;
$this->identifier = 'id_jxblog_category';
$this->className = 'JXBlogCategory';
$this->module = $this;
$this->lang = true;
$this->bootstrap = true;
$this->languages = Language::getLanguages(false);
$this->default_language = Configuration::get('PS_LANG_DEFAULT');
$this->context = Context::getContext();
$this->translator = Context::getContext()->getTranslator();
if (Shop::isFeatureActive()) {
Shop::addTableAssociation($this->table, array('type' => 'shop'));
}
$id_category = (int)Tools::getValue('id_jxblog_category');
if (!$id_category && !Tools::getIsset('add'.$this->table)) {
$id_category = 2;
}
$this->_category = new JXBlogCategory($id_category);
$this->_join = 'LEFT JOIN '._DB_PREFIX_.$this->table.'_shop jxs ON a.id_jxblog_category=jxs.id_jxblog_category && jxs.id_shop IN('.implode(',', Shop::getContextListShopID()).')';
$this->_filter = 'AND a.`id_parent_category` = '.$id_category.' AND a.id_jxblog_category > 2';
$this->_select = 'jxs.id_shop';
$this->_defaultOrderBy = 'a.position';
$this->_defaultOrderWay = 'ASC';
$this->_default_pagination = 10;
$this->_pagination = array(10, 20, 50, 100);
$this->_orderBy = Tools::getValue($this->table.'Orderby');
$this->_orderWay = Tools::getValue($this->table.'Orderway');
$this->orderBy = 'position';
$this->bulk_actions = array(
'delete' => array(
'text' => $this->l('Delete selected'),
'icon' => 'icon-trash',
'confirm' => $this->l('Delete selected items?')
)
);
if (Shop::isFeatureActive() && Shop::getContext() != Shop::CONTEXT_SHOP) {
$this->_group = 'GROUP BY a.id_jxblog_category';
}
$this->fields_list = array(
'id_jxblog_category' => array(
'title' => $this->l('ID Category'),
'width' => 100,
'type' => 'text',
'search' => true,
'orderby' => true
),
'name' => array(
'title' => $this->l('Name'),
'width' => 440,
'type' => 'text',
'search' => true,
'orderby' => true,
'lang' => true
),
'position' => array(
'title' => $this->l('Position'),
'filter_key' => 'a!position',
'position' => 'position',
'align' => 'center'
),
'active' => array(
'title' => $this->l('Displayed'),
'active' => 'status',
'type' => 'bool',
'class' => 'fixed-width-xs',
'align' => 'center',
'ajax' => true,
'orderby' => false
)
);
parent::__construct();
$this->imageManager = new JXBlogImageManager($this->module);
if (!$this->module->active) {
Tools::redirectAdmin($this->context->link->getAdminLink('AdminHome'));
}
}
public function setMedia($isNewTheme = false)
{
$this->context->controller->addCss($this->module->modulePath.'views/css/jxblog_admin.css');
parent::setMedia($isNewTheme);
}
public function init()
{
parent::init();
}
public function renderView()
{
return $this->renderList();
}
public function initToolbar()
{
// add button "New" to each categories listing
if ($this->display == 'view') {
$this->toolbar_btn['new'] = array(
'href' => self::$currentIndex . '&add' . $this->table . '&id_parent=' . (int) Tools::getValue('id_jxblog_category') . '&token=' . $this->token,
'desc' => $this->l('Add New'),
);
}
parent::initToolbar();
// add different back buttons to each category listing
if (!$this->lite_display
&& isset($this->toolbar_btn['back']['href'])
&& !empty($this->_category)
&& $this->_category->id_parent_category
&& $this->_category->id_parent_category != 2
) {
$this->toolbar_btn['back']['href'] .= '&viewjxblog_category&id_jxblog_category=' . (int) $this->_category->id_parent_category;
}
}
public function renderList()
{
$this->addRowAction('view');
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->helper = new HelperBlog();
// create categories breadcrumb
$this->helper->buildBreadCrumbs($this->_category->id_jxblog_category);
$categories_tree = $this->helper->getBreadCrumbs();
// add edit link to breadcrumb
if (!empty($categories_tree)) {
$link = Context::getContext()->link;
foreach ($categories_tree as $k => $tree) {
$categories_tree[$k]['edit_link'] = $link->getAdminLink('AdminJXBlogCategories', true) . '&id_jxblog_category=' . (int) $tree['id_jxblog_category'] . '&updatejxblog_category';
}
}
$this->tpl_list_vars['categories_tree'] = $categories_tree;
$this->tpl_list_vars['categories_tree_current_id'] = $this->_category->id;
return parent::renderList();
}
public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
{
parent::getList($id_lang);
// add view button to category if it has children
if ($this->_list && count($this->_list)) {
foreach ($this->_list as $item) {
if (!JXBlogCategory::getChildrenCategories($item['id_jxblog_category'])) {
$this->addRowActionSkipList('view', array($item['id_jxblog_category']));
}
}
}
}
public function initContent()
{
if ($this->errors) {
$this->content = $this->renderForm();
$this->context->smarty->assign('content', $this->content);
} elseif (Tools::getIsset('delete'.$this->table)) {
$this->content = $this->confirmDeleteForm();
parent::initContent();
} else {
parent::initContent();
}
}
/**
* Confirm delete form. Used to determine what to do with the category data(posts, children categories)
* when you delete the category
*
* @return string
*/
public function confirmDeleteForm()
{
$availableCategories = JXBlogCategory::getAllCategoriesWithInfo();
$options = array();
foreach ($availableCategories as $key => $category) {
if ($category['id_jxblog_category'] > 1 &&$category['id_jxblog_category'] != Tools::getValue('id_jxblog_category')) {
$options[$key]['id'] = $category['id_jxblog_category'];
$options[$key]['type'] = $category['name'];
}
}
$this->fields_form = array(
'legend' => array(
'title' => $this->l('What do you want to do with products and categories that are related to the category?')
),
'input' => array(
array(
'type' => 'hidden',
'name' => 'id_jxblog_category',
'value' => Tools::getValue('id_jxblog_category')
),
array(
'type' => 'radio',
'name' => 'deleteAction',
'label' => '',
'col' => 12,
'values' => array(
array(
'id' => 'deleteAction',
'value' => 1,
'label' => $this->l('Remove the category and all children categories and leave their posts without main category')
),
array(
'id' => 'deleteAction',
'value' => 2,
'label' => $this->l('Remove the category and all children categories and all their posts')
),
array(
'id' => 'deleteAction',
'value' => 3,
'label' => $this->l('Remove the category and only its posts but leave children categories')
),
array(
'id' => 'deleteAction',
'value' => 4,
'label' => $this->l('Select new main category from the list below')
)
)
),
array(
'type' => 'select',
'name' => 'newDefaultCategory',
'label' => '',
'col' => 12,
'options' => array(
'query' => $options,
'id' => 'id',
'name' => 'type'
)
)
),
'buttons' => array(
array(
'title' => $this->l('Delete'),
'class' => 'button pull-right btn btn-danger',
'name' => 'confirmDelete',
'type' => 'submit'
)
)
);
$this->fields_value['deleteAction'] = 1;
$this->submit_action = 'confirmDelete';
return parent::renderForm();
}
public function renderForm()
{
$categoriesTree = $this->helper->buildTree();
$id_category = Tools::getValue('id_jxblog_category');
$unidentified = new Group(Configuration::get('PS_UNIDENTIFIED_GROUP'));
$guest = new Group(Configuration::get('PS_GUEST_GROUP'));
$default = new Group(Configuration::get('PS_CUSTOMER_GROUP'));
$unidentified_group_information = sprintf($this->l('%s - All people without a valid customer account.'), '<b>'.$unidentified->name[$this->context->language->id].'</b>');
$guest_group_information = sprintf($this->l('%s - Customer who placed an order with the guest checkout.'), '<b>'.$guest->name[$this->context->language->id].'</b>');
$default_group_information = sprintf($this->l('%s - All people who have created an account on this site.'), '<b>'.$default->name[$this->context->language->id].'</b>');
$image = false;
$thumb = false;
if (Tools::getIsset('id_jxblog_category') && Tools::getValue('id_jxblog_category')) {
if (file_exists($this->module->modulePath.'img/c/'.Tools::getValue('id_jxblog_category').'.jpg')) {
$image = '<img class="imgm img-thumbnail" src="'.$this->module->_link.'img/c/'.Tools::getValue('id_jxblog_category').'.jpg" width="300" />';
}
if (file_exists($this->module->modulePath.'img/ct/'.Tools::getValue('id_jxblog_category').'.jpg')) {
$thumb = '<img class="imgm img-thumbnail" src="'.$this->module->_link.'img/ct/'.Tools::getValue('id_jxblog_category').'.jpg" width="150" />';
}
}
$selected_categories = array();
if (Tools::getIsset('id_parent') && Tools::getValue('id_parent')) {
$selected_categories[] = Tools::getValue('id_parent');
} elseif ($this->_category->id_parent_category) {
$selected_categories[] = $this->_category->id_parent_category;
} else {
$selected_categories[] = 2;
}
$this->fields_form = array(
'input' => array(
array(
'type' => 'text',
'class' => 'copy2friendlyUrl',
'hint' => $this->l('Invalid characters: <>;=#{}'),
'label' => $this->l('Name'),
'name' => 'name',
'required' => true,
'desc' => $this->l('Enter the blog category name'),
'lang' => true,
'col' => 3
),
array(
'type' => 'text',
'hint' => $this->l('Only letters, numbers, underscore (_) and the minus (-) character are allowed.'),
'label' => $this->l('Friendly URL'),
'name' => 'link_rewrite',
'required' => true,
'desc' => $this->l('Enter the blog category friendly URL. Will be used as a link to the category in the "Friendly URL" mode'),
'lang' => true,
'col' => 3
),
array(
'type' => 'categories',
'label' => $this->l('Parent category'),
'name' => 'id_parent_category',
'tree' => array(
'id' => 'blog-categories-tree',
'selected_categories' => $selected_categories,
'disabled_categories' => (!Tools::isSubmit('add' . $this->table) && !Tools::isSubmit('submitAdd' . $this->table)) ? array($id_category) : null,
'root_category' => 1,
'set_data' => $categoriesTree,
'use_search' => true,
'use_checkbox' => false
),
),
array(
'type' => 'textarea',
'label' => $this->l('Short description'),
'name' => 'short_description',
'desc' => $this->l('Enter the category short description'),
'lang' => true,
'col' => 6,
'autoload_rte' => true
),
array(
'type' => 'textarea',
'label' => $this->l('Full description'),
'name' => 'description',
'desc' => $this->l('Enter the category full description'),
'lang' => true,
'col' => 6,
'autoload_rte' => true
),
array(
'type' => 'text',
'hint' => $this->l('Only letters, numbers, underscore (_) and the minus (-) character are allowed.'),
'label' => $this->l('Meta Keywords'),
'name' => 'meta_keyword',
'desc' => $this->l('Enter Your Category Meta Keywords. Separated by comma(,) '),
'lang' => true,
'col' => 6
),
array(
'type' => 'textarea',
'label' => $this->l('Meta Description'),
'name' => 'meta_description',
'desc' => $this->l('Enter the category meta description'),
'lang' => true,
'col' => 6,
'autoload_rte' => false
),
array(
'type' => 'file',
'label' => $this->l('Image'),
'name' => 'image',
'value' => true,
'display_image' => false,
'image' => $image,
'desc' => $this->l('Only .jpg images are allowed')
),
array(
'type' => 'file',
'label' => $this->l('Image thumbnail'),
'name' => 'thumbnail',
'value' => true,
'display_image' => false,
'image' => $thumb,
'desc' => $this->l('Only .jpg images are allowed')
),
array(
'type' => 'group',
'label' => $this->l('Group access'),
'name' => 'groupBox',
'values' => Group::getGroups(Context::getContext()->language->id),
'info_introduction' => $this->l('You now have three default customer groups.'),
'unidentified' => $unidentified_group_information,
'guest' => $guest_group_information,
'customer' => $default_group_information,
'hint' => $this->l('Mark all of the customer groups which you would like to have access to this category.')
),
array(
'type' => 'text',
'hint' => $this->l('Only letters, numbers, underscore (_) and the minus (-) character are allowed.'),
'label' => $this->l('Badge'),
'name' => 'badge',
'desc' => $this->l('Enter the badge which will unify the category on the list'),
'lang' => true,
'col' => 6
),
array(
'type' => 'switch',
'label' => $this->l('Status'),
'name' => 'active',
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Enabled'),
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('Disabled'),
)
)
)
),
'submit' => array(
'title' => $this->l('Save'),
'class' => 'button pull-right btn btn-default'
)
);
$this->tpl_form_vars['PS_ALLOW_ACCENTED_CHARS_URL'] = (int)Configuration::get('PS_ALLOW_ACCENTED_CHARS_URL');
if (Shop::isFeatureActive()) {
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->l('Shop association:'),
'name' => 'checkBoxShopAsso'
);
}
$category_groups_ids = array();
if ($id_category) {
$category = new JXBlogCategory($id_category);
$category_groups_ids = $category->getGroups();
}
$groups = Group::getGroups($this->context->language->id);
if (!count($category_groups_ids)) {
$preselected = array(Configuration::get('PS_UNIDENTIFIED_GROUP'), Configuration::get('PS_GUEST_GROUP'), Configuration::get('PS_CUSTOMER_GROUP'));
$category_groups_ids = array_merge($category_groups_ids, $preselected);
}
foreach ($groups as $group) {
$this->fields_value['groupBox_'.$group['id_group']] = Tools::getValue('groupBox_'.$group['id_group'], (in_array($group['id_group'], $category_groups_ids)));
}
if (!($JXBlogCategory = $this->loadObject(true))) {
return;
}
return parent::renderForm();
}
public function validateRules($class_name = false)
{
parent::validateRules();
}
public function postProcess()
{
$this->helper = new HelperBlog();
if (Tools::isSubmit('submitAddjxblog_category') && !Tools::getIsset('confirmDelete')) {
$this->validateRules();
if (count($this->errors)) {
return false;
}
$id_category = (int)Tools::getValue('id_jxblog_category');
if (!$id_category) {
$category = new JXBlogCategory();
} else {
$category = new JXBlogCategory($id_category);
}
if (!$id_category) {
$category->date_add = date('y-m-d H:i:s');
$category->position = (int)$category->getNewPosition(Tools::getValue('id_parent_category'));
} else {
$category->date_upd = date('y-m-d H:i:s');
if ($category->id_parent_category != Tools::getValue('id_parent_category')) {
$category->position = $category->getNewPosition(Tools::getValue('id_parent_category'));
}
}
if (!$parent = Tools::getValue('id_parent_category')) {
$category->id_parent_category = $category->id_parent_category ? $category->id_parent_category : 0;
} else {
$category->id_parent_category = (int)$parent;
}
$category->active = Tools::getValue('active');
foreach ($this->languages as $lang) {
$category->name[$lang['id_lang']] = Tools::getValue('name_'.$lang['id_lang']);
$category->link_rewrite[$lang['id_lang']] = Tools::getValue('link_rewrite_'.$lang['id_lang']);
if (!$category->link_rewrite[$lang['id_lang']]) {
$category->link_rewrite[$lang['id_lang']] = Tools::getValue(
'link_rewrite_'.$this->default_language
);
}
if (!$category->link_rewrite[$lang['id_lang']]) {
$category->link_rewrite[$lang['id_lang']] = Tools::getValue(
'link_rewrite_'.$this->default_language
);
}
if ($category->checkCategoryNameExistence(
$category->id,
$category->name[$lang['id_lang']],
$lang['id_lang']
)
) {
$this->errors[] = sprintf(
$this->l('The category with such name already exists!. Name: %s, Language: %s'),
$category->name[$lang['id_lang']],
$lang['iso_code']
);
}
if ($category->checkFriendlyUrlNameExistence(
$category->id,
$category->link_rewrite[$lang['id_lang']],
$lang['id_lang']
)
) {
$this->errors[] = sprintf(
$this->l('The category with such Friendly Url already exists!. Name: %s, Language: %s'),
$category->link_rewrite[$lang['id_lang']],
$lang['iso_code']
);
}
$category->description[$lang['id_lang']] = Tools::getValue('description_'.$lang['id_lang']);
$category->short_description[$lang['id_lang']] = Tools::getValue('short_description_'.$lang['id_lang']);
$category->meta_keyword[$lang['id_lang']] = Tools::getValue('meta_keyword_'.$lang['id_lang']);
$category->meta_description[$lang['id_lang']] = Tools::getValue('meta_description_'.$lang['id_lang']);
$category->badge[$lang['id_lang']] = Tools::getValue('badge_'.$lang['id_lang']);
}
if ($this->errors) {
return false;
}
if (!$category->save()) {
$this->errors[] = Tools::displayError('An error has occurred: Can\'t save the current object');
}
// upload category images after successful saving
$imageManger = new JXBlogImageManager($this->module);
if (!Tools::isEmpty(Tools::getValue('image')) && Tools::getValue('image')) {
if ($error = $imageManger->uploadImage($category->id, $_FILES['image'], 'category')) {
$this->errors[] = $error;
}
}
if (!Tools::isEmpty(Tools::getValue('thumbnail')) && Tools::getValue('thumbnail')) {
if ($error = $imageManger->uploadImage($category->id, $_FILES['thumbnail'], 'category_thumb')) {
$this->errors[] = $error;
}
}
// redirect to the categories list page if no errors occurred
if (!$this->errors) {
if (Tools::getIsset('id_parent_category') && Tools::getValue('id_parent_category') > 2) {
//redirent to the parent category listing and avoid wrong redirection if parent category is one of the default
Tools::redirectAdmin($this->context->link->getAdminLink('AdminJXBlogCategories').'&conf=4&id_jxblog_category='.Tools::getValue('id_parent_category').'&view'.$this->table);
}
// redirect to default category listing
Tools::redirectAdmin($this->context->link->getAdminLink('AdminJXBlogCategories').'&conf=4');
}
} elseif (Tools::isSubmit('confirmDelete') && $id_jxblog_category = Tools::getValue('id_jxblog_category')) {
$post = new JXBlogPost();
$category = new JXBlogCategory($id_jxblog_category);
switch (Tools::getValue('deleteAction')) {
case 1:
$this->removeCategoryWithChildrenAction($this->helper->buildTree($id_jxblog_category));
$post->resetDefaultCategory($id_jxblog_category);
break;
case 2:
$this->removeCategoryWithChildrenAction($this->helper->buildTree($id_jxblog_category), 'remove');
$posts = $post->getPostsByDefaultCategory($id_jxblog_category);
if ($posts) {
foreach ($posts as $post) {
$post = new JXBlogPost($post['id_jxblog_post']);
$post->delete();
}
}
break;
case 3:
// remove category's posts
$posts = $post->getPostsByDefaultCategory($id_jxblog_category);
if ($posts) {
foreach ($posts as $post) {
$post = new JXBlogPost($post['id_jxblog_post']);
$post->delete();
}
}
$childrenCategories = JXBlogCategory::getChildrenCategories($id_jxblog_category);
// set all related categories to the home category
if ($childrenCategories) {
foreach ($childrenCategories as $childrenCategory) {
$chCategory = new JXBlogCategory($childrenCategory['id_category']);
$chCategory->id_parent_category = 2;
$chCategory->position = $chCategory->getNewPosition();
$chCategory->update();
}
}
break;
case 4:
$post->resetDefaultCategory($id_jxblog_category, Tools::getValue('newDefaultCategory'));
$childrenCategories = JXBlogCategory::getChildrenCategories($id_jxblog_category);
if ($childrenCategories) {
foreach ($childrenCategories as $childrenCategory) {
$chCategory = new JXBlogCategory($childrenCategory['id_category']);
$chCategory->id_parent_category = Tools::getValue('newDefaultCategory');
$chCategory->position = $chCategory->getNewPosition();
$chCategory->update();
}
}
break;
}
$category->delete();
if (!$this->errors) {
if (Tools::getValue('deleteAction') == 4 && Tools::getValue('newDefaultCategory')) {
//redirent to the parent category listing and avoid wrong redirection if parent category is one of the default
Tools::redirectAdmin($this->context->link->getAdminLink('AdminJXBlogCategories').'&conf=1&id_jxblog_category='.Tools::getValue('newDefaultCategory').'&view'.$this->table);
}
// redirect to default category listing
Tools::redirectAdmin($this->context->link->getAdminLink('AdminJXBlogCategories').'&conf=1');
}
} elseif (!Tools::getIsset('delete'.$this->table)) {
parent::postProcess();
}
}
public function ajaxProcessStatusjxblogCategory()
{
if (!$id_category = (int)Tools::getValue('id_jxblog_category')) {
die(json_encode(array('success' => false, 'error' => true, 'text' => $this->l('Failed to update the status'))));
} else {
$category = new JXBlogCategory((int)$id_category);
if (Validate::isLoadedObject($category)) {
$category->active = $category->active == 1 ? 0 : 1;
$category->save() ?
die(json_encode(array('success' => true, 'text' => $this->l('The status has been updated successfully')))) :
die(json_encode(array('success' => false, 'error' => true, 'text' => $this->l('Failed to update the status'))));
}
}
}
public function ajaxProcessUpdatePositions()
{
$id_category_to_move = (int)Tools::getValue('id');
$way = (int)Tools::getValue('way');
$positions = Tools::getValue('jxblog_category');
if (is_array($positions)) {
foreach ($positions as $key => $value) {
$pos = explode('_', $value);
if (isset($pos[2]) && $pos[2] == $id_category_to_move) {
$position = $key;
break;
}
}
}
$category = new JXBlogCategory($id_category_to_move);
if (Validate::isLoadedObject($category)) {
if (isset($position) && $category->updatePosition($way, $position)) {
die(true);
} else {
die('{"hasError" : true, errors : "Cannot update categories position"}');
}
} else {
die('{"hasError" : true, "errors" : "This category cannot be loaded"}');
}
}
/**
* Remove category and manage related data depending on the selected action
*
* @param $list
* @param string $action
*
* @return bool
*/
private function removeCategoryWithChildrenAction($list, $action = 'reset')
{
$result = true;
$post = new JXBlogPost();
if (is_array($list) && count($list)) {
foreach ($list as $item) {
if (isset($item['children']) && is_array($item['children'])) {
$this->removeCategoryWithChildrenAction($item['children'], $action);
}
$category = new JXBlogCategory($item['id_category']);
// if we want to delete children categories but want to save all post that are related we need to set posts to default category
if ($action == 'reset') {
$result &= $post->resetDefaultCategory($category->id_jxblog_category);
//if we want to remove categories with related posts
} elseif ($action == 'remove') {
$posts = $post->getPostsByDefaultCategory($category->id_jxblog_category);
if ($posts) {
foreach ($posts as $post) {
$post = new JXBlogPost($post['id_jxblog_post']);
$result &= $post->delete();
}
}
}
$result &= $category->delete();
}
}
return $result;
}
}

View File

@@ -0,0 +1,626 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class AdminJXBlogImagesController extends ModuleAdminController
{
public $translator;
public $imageTypes;
public $imageManager;
public function __construct()
{
$this->translator = Context::getContext()->getTranslator();
$this->table = 'jxblog_image';
$this->list_id = $this->table;
$this->identifier = 'id_jxblog_image';
$this->className = 'JXBlogImage';
$this->module = $this;
$this->lang = false;
$this->bootstrap = true;
$this->context = Context::getContext();
$this->_defaultOrderBy = 'id_jxblog_image';
$this->_defaultOrderWay = 'DESC';
$this->_default_pagination = 10;
$this->_pagination = array(10, 20, 50, 100);
$this->_orderBy = Tools::getValue($this->table.'Orderby');
$this->_orderWay = Tools::getValue($this->table.'Orderway');
$this->bulk_actions = array(
'delete' => array(
'text' => $this->l('Delete selected'),
'icon' => 'icon-trash',
'confirm' => $this->l('Delete selected items?')
)
);
$this->fields_list = array(
'id_jxblog_image' => array(
'title' => $this->l('ID Image'),
'width' => 100,
'type' => 'text',
'search' => true,
'orderby' => true
),
'name' => array(
'title' => $this->l('Name'),
'width' => 440,
'type' => 'text',
'search' => true,
'orderby' => true,
'lang' => true
),
'width' => array(
'title' => $this->l('Width'),
'width' => 150,
'type' => 'text',
'search' => true,
'orderby' => true,
'lang' => true
),
'height' => array(
'title' => $this->l('Height'),
'width' => 150,
'type' => 'text',
'search' => true,
'orderby' => true,
'lang' => true
),
'category' => array(
'title' => $this->l('Categories'),
'active' => 'category',
'type' => 'bool',
'class' => 'fixed-width-xs',
'align' => 'center',
'ajax' => true,
'orderby' => false
),
'category_thumb' => array(
'title' => $this->l('Categories Thumbnails'),
'active' => 'category_thumb',
'type' => 'bool',
'class' => 'fixed-width-xs',
'align' => 'center',
'ajax' => true,
'orderby' => false
),
'post' => array(
'title' => $this->l('Posts'),
'active' => 'post',
'type' => 'bool',
'class' => 'fixed-width-xs',
'align' => 'center',
'ajax' => true,
'orderby' => false
),
'post_thumb' => array(
'title' => $this->l('Posts Thumbnails'),
'active' => 'post_thumb',
'type' => 'bool',
'class' => 'fixed-width-xs',
'align' => 'center',
'ajax' => true,
'orderby' => false
),
'user' => array(
'title' => $this->l('Users'),
'active' => 'user',
'type' => 'bool',
'class' => 'fixed-width-xs',
'align' => 'center',
'ajax' => true,
'orderby' => false
)
);
$this->languages = Language::getLanguages(false);
$this->default_language = Configuration::get('PS_LANG_DEFAULT');
parent::__construct();
$this->imageManager = new JXBlogImageManager($this->module);
if (!$this->module->active) {
Tools::redirectAdmin($this->context->link->getAdminLink('AdminHome'));
}
}
public function renderList()
{
$this->addRowAction('edit');
$this->addRowAction('delete');
return parent::renderList();
}
public function initContent()
{
$this->content = '';
if (Tools::isSubmit('updateDefaultImages')) {
$this->updateDefaultImages();
$this->regenerateImages('default');
}
if (Tools::isSubmit('regenerateImages')) {
$this->regenerateImages(Tools::getValue('regenerate_type'));
}
if (Tools::getIsset('ajax') && Tools::getValue('ajax')) {
$action = str_replace($this->table, '', Tools::getValue('action'));
$id_image_type = Tools::getValue('id_jxblog_image');
if (!$id_image_type || !$action) {
die(json_encode(array('success' => false, 'error' => true, 'text' => $this->l('Failed to update the status'))));
}
$this->ajaxUpdate($action, $id_image_type);
} else {
if ($this->display == 'edit' || $this->display == 'add') {
$this->content .= $this->renderForm();
} else {
$this->content .= $this->renderList();
$this->content .= $this->renderRegenerateForm();
$this->content .= $this->renderDefaultImagesForm();
}
$this->context->smarty->assign(
array(
'content' => $this->content,
'url_post' => self::$currentIndex.'&token='.$this->token,
'show_page_header_toolbar' => $this->show_page_header_toolbar,
'page_header_toolbar_title' => $this->page_header_toolbar_title,
'page_header_toolbar_btn' => $this->page_header_toolbar_btn
)
);
}
}
public function renderForm()
{
$this->fields_form = array(
'input' => array(
array(
'type' => 'text',
'hint' => $this->l('Letters, underscores and hyphens only (e.g. "small_custom", "post_medium", "large", "thickbox_extra-large").'),
'label' => $this->l('Name'),
'name' => 'name',
'required' => true,
'desc' => $this->l('Enter the image type name'),
'col' => 3
),
array(
'type' => 'text',
'label' => $this->l('Width'),
'hint' => $this->l('Maximum image width in pixels.'),
'name' => 'width',
'required' => true,
'desc' => $this->l('Enter the image type width'),
'col' => 3,
'suffix' => $this->l('px')
),
array(
'type' => 'text',
'label' => $this->l('Height'),
'hint' => $this->l('Maximum image height in pixels.'),
'name' => 'height',
'required' => true,
'desc' => $this->l('Enter the image type height'),
'col' => 3,
'suffix' => $this->l('px')
),
array(
'type' => 'switch',
'label' => $this->l('Categories'),
'hint' => $this->l('This type will be used for Blog categories images.'),
'name' => 'category',
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Enabled')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('Disabled')
)
)
),
array(
'type' => 'switch',
'label' => $this->l('Categories Thumbnails'),
'hint' => $this->l('This type will be used for Blog categories thumbnails images.'),
'name' => 'category_thumb',
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Enabled')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('Disabled')
)
)
),
array(
'type' => 'switch',
'label' => $this->l('Posts'),
'hint' => $this->l('This type will be used for Blog posts images.'),
'name' => 'post',
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Enabled')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('Disabled')
)
)
),
array(
'type' => 'switch',
'label' => $this->l('Posts Thumbnails'),
'hint' => $this->l('This type will be used for Blog posts thumbnails.'),
'name' => 'post_thumb',
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Enabled')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('Disabled')
)
)
),
array(
'type' => 'switch',
'label' => $this->l('Blog users'),
'hint' => $this->l('This type will be used for not registered Blog users.'),
'name' => 'user',
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Enabled')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('Disabled')
)
)
)
),
'submit' => array(
'title' => $this->l('Save'),
'class' => 'button pull-right btn btn-default'
)
);
return parent::renderForm();
}
public function renderDefaultImagesForm()
{
$defaultImages = $this->getDefaultImages();
$this->fields_form = array(
'legend' => array(
'title' => $this->l('Default images')
),
'input' => array(
array(
'type' => 'multilingual_image',
'name' => 'image_default',
'label' => $this->l('Default image'),
'hint' => $this->l('Upload default image.'),
'folder' => false,
'images' => $defaultImages['image_default']
),
array(
'type' => 'multilingual_image',
'name' => 'image_category',
'label' => $this->l('Categories default image'),
'hint' => $this->l('Upload default image for categories.'),
'folder' => 'c',
'images' => $defaultImages['image_category']
),
array(
'type' => 'multilingual_image',
'name' => 'image_category_thumb',
'label' => $this->l('Categories thumbnails default image'),
'hint' => $this->l('Upload default image for categories thumbnails.'),
'folder' => 'ct',
'images' => $defaultImages['image_category_thumb']
),
array(
'type' => 'multilingual_image',
'name' => 'image_post',
'label' => $this->l('Posts default image'),
'hint' => $this->l('Upload default image for posts.'),
'folder' => 'p',
'images' => $defaultImages['image_post']
),
array(
'type' => 'multilingual_image',
'name' => 'image_post_thumb',
'label' => $this->l('Posts thumbnail default image'),
'hint' => $this->l('Upload default image for posts thumbnails.'),
'folder' => 'pt',
'images' => $defaultImages['image_post_thumb']
),
array(
'type' => 'multilingual_image',
'name' => 'image_user',
'label' => $this->l('Users default image'),
'hint' => $this->l('Upload default image for users.'),
'folder' => 'u',
'images' => $defaultImages['image_user']
)
),
'submit' => array(
'title' => $this->l('Save'),
'class' => 'button pull-right btn btn-default',
'name' => 'updateDefaultImages',
'id' => ''
)
);
// add extra fields from related modules
$extraFields = array_values(Hook::exec('displayJxblogImageManagerExtra', array(), null, true));
if ($extraFields) {
foreach ($extraFields[0] as $filed) {
$this->fields_form['input'][] = $filed;
}
}
return parent::renderForm();
}
public function renderRegenerateForm()
{
$this->fields_form = array(
'legend' => array(
'title' => $this->l('Regenerate images')
),
'input' => array(
array(
'type' => 'select',
'name' => 'regenerate_type',
'label' => $this->l('Select images type to regenerate'),
'desc' => $this->l('All images will regenerated. All old images will be lost.'),
'options' => array(
'query' => array(
array(
'id' => 'all',
'type' => $this->l('All')
),
array(
'id' => 'category',
'type' => $this->l('Categories')
),
array(
'id' => 'category_thumb',
'type' => $this->l('Categories thumbnails')
),
array(
'id' => 'post',
'type' => $this->l('Posts')
),
array(
'id' => 'post_thumb',
'type' => $this->l('Posts thumbnails')
),
array(
'id' => 'user',
'type' => $this->l('Users')
)
),
'id' => 'id',
'name' => 'type'
)
)
),
'submit' => array(
'title' => $this->l('Regenerate'),
'class' => 'button pull-right btn btn-default',
'id' => 'regenerate-images',
'name' => 'regenerateImages'
)
);
return parent::renderForm();
}
public function validateRules($class_name = false)
{
// check if this image type name is not already used
if (!Tools::isEmpty(Tools::getValue('name')) && JXBlogImage::checkIfNameExists(Tools::getValue('name'), Tools::getValue('id_jxblog_image'))) {
$this->errors[] = $this->l('The image type with this name already exists, you can\'t use the same name more than once.');
}
parent::validateRules();
}
public function postProcess()
{
$id_jxblog_image = Tools::getValue('id_jxblog_image');
if (!Tools::isSubmit('updateDefaultImages') && !Tools::isSubmit('regenerateImages') && Tools::isSubmit('submitAddjxblog_image')) {
// remove all old images related to current image type in order to delete images if they are no more related to this type after saving
if ($this->module->imagesAutoRegenerate && $id_jxblog_image && !$this->imageManager->removeImageTypeImages($id_jxblog_image)) {
$this->errors[] = $this->lang('Fail to remove old images', array(), 'Modules.JXBlog.Admin');
}
$this->validateRules(false);
if (count($this->errors)) {
parent::postProcess();
return false;
}
if ($id_jxblog_image = Tools::getValue('id_jxblog_image')) {
$blogimage = new JXBlogImage($id_jxblog_image);
} else {
$blogimage = new JXBlogImage();
}
$blogimage->name = Tools::getValue('name');
$blogimage->width = Tools::getValue('width');
$blogimage->height = Tools::getValue('height');
$blogimage->category = Tools::getValue('category');
$blogimage->category_thumb = Tools::getValue('category_thumb');
$blogimage->post = Tools::getValue('post');
$blogimage->post_thumb = Tools::getValue('post_thumb');
$blogimage->user = Tools::getValue('user');
if (!$blogimage->save()) {
$this->errors[] = $this->lang('An error occurred during object regeneration', array(), 'Modules.JXBlog.Admin');
} else {
$result = true;
// check if images auto regeneration option is enabled
if ($this->module->imagesAutoRegenerate) {
foreach (array_keys($this->module->imageTypes) as $imageType) {
if ($imageType == 'default' || ($imageType != 'default' && $blogimage->$imageType)) {
$result &= $this->imageManager->regenerateTypeImages($imageType, false, $blogimage->name);
}
}
}
if (!$result) {
$this->errors[] = $this->lang('An error occurred during images regeneration', array(), 'Modules.JXBlog.Admin');
} else {
Tools::redirectAdmin($this->context->link->getAdminLink('AdminJXBlogImages').'&conf=4');
}
}
} elseif (!Tools::isSubmit('updateDefaultImages') && !Tools::isSubmit('regenerateImages')) {
parent::postProcess();
}
}
/**
* Update status for image content type
*
* @param $action
* @param $id_image_type
*/
public function ajaxUpdate($action, $id_image_type)
{
$image = new JXBlogImage((int)$id_image_type);
if (Validate::isLoadedObject($image)) {
$image->$action = $image->$action == 1 ? 0 : 1;
if ($image->save()) {
// check if images auto regeneration option is enabled
if ($this->module->imagesAutoRegenerate) {
if ($image->$action) {
if (!$this->imageManager->regenerateTypeImages($action, false, $image->name)) {
die(json_encode(
array(
'success' => false,
'text' => $this->l('The status has been updated successfully but images were not generated properly. Please, regenerate it manually.')
)
));
}
} else {
if (!$this->imageManager->removeImageTypeImages($image->id, $action)) {
die(json_encode(
array(
'success' => false,
'text' => $this->l('The status has been updated successfully but images were not removed properly. Please, regenerate it manually.')
)
));
}
}
}
die(json_encode(
array(
'success' => true,
'text' => $this->l('The status has been updated successfully')
)
));
} else {
die(json_encode(
array(
'success' => false,
'error' => true,
'text' => $this->l('Failed to update the status')
)
));
}
}
}
public function updateDefaultImages()
{
$errors = array();
foreach ($this->module->imageTypes as $key => $type) {
foreach ($this->languages as $language) {
if (Tools::getValue('image_'.$key.'_'.$language['id_lang'])) {
if ($error = $this->imageManager->uploadImage($language['iso_code'], $_FILES['image_'.$key.'_'.$language['id_lang']], $key)) {
$errors[] = $error;
}
}
}
}
Hook::exec('actionUpdateJxblogImages', array('values' => Tools::getAllValues(), 'images' => $_FILES));
if (count($errors)) {
$this->errors[] = $errors;
}
$this->confirmations[] = $this->l('Everything is cool!');
}
public function getDefaultImages()
{
$defaultImages = array();
foreach ($this->module->imageTypes as $key => $type) {
foreach ($this->languages as $language) {
$defaultImages['image_'.$key][$language['id_lang']] = false;
if ($key == 'default') {
if (file_exists($this->module->modulePath.'img/'.$language['iso_code'].'.jpg')) {
$defaultImages['image_'.$key][$language['id_lang']] = $this->module->_link.'img/'.$language['iso_code'].'.jpg';
}
} else {
if (file_exists($this->module->modulePath.'img/'.$type[0].$language['iso_code'].'.jpg')) {
$defaultImages['image_'.$key][$language['id_lang']] = $this->module->_link.'img/'.$type[0].$language['iso_code'].'.jpg';
}
}
}
}
return $defaultImages;
}
/**
* Launch images regeneration
*
* @param $type
*/
public function regenerateImages($type)
{
$result = true;
if ($type == 'all') {
$result &= $this->imageManager->regenerateTypeImages('default');
$result &= $this->imageManager->regenerateTypeImages('category');
$result &= $this->imageManager->regenerateTypeImages('category_thumb');
$result &= $this->imageManager->regenerateTypeImages('post');
$result &= $this->imageManager->regenerateTypeImages('post_thumb');
$result &= $this->imageManager->regenerateTypeImages('user');
} else {
$result &= $this->imageManager->regenerateTypeImages($type);
}
if (!$result) {
$this->errors[] = $this->l('An error occurred during the images regeneration');
} else {
$this->confirmations[] = $this->l('All images are regenerated successfully');
}
}
}

View File

@@ -0,0 +1,90 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class AdminJXBlogMainSettingsController extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
parent::__construct();
$this->fields_options = array(
'general' => array(
'title' => $this->l('Comments settings '),
'fields' => array(
'JXBLOG_IMAGES_AUTO_REGENERATION' => array(
'title' => $this->l('Image regeneration'),
'desc' => $this->l('Regenerate images automatically after each changing?'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool',
'default' => '0'
),
'JXBLOG_DISPLAY_BLOG_PAGE' => array(
'title' => $this->l('Display Blog main page'),
'desc' => $this->l(
'Display Blog main page with all blog content listed instead of Blog category page'
),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool',
'default' => '0'
),
'JXBLOG_DISPLAY_PRODUCTS_ON_BLOG_PAGE' => array(
'title' => $this->l('Display Products on Blog main page'),
'desc' => $this->l('Display products on Blog main page after all blog content listed'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool',
'default' => '0'
),
'JXBLOG_DISPLAY_POST_AUTHOR' => array(
'title' => $this->l('Display author'),
'desc' => $this->l('Display an author of the post on the front-end?'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool',
'default' => '0'
),
'JXBLOG_DISPLAY_POST_VIEWS' => array(
'title' => $this->l('Display views'),
'desc' => $this->l('Display on the front-end how many times the post has been viewed?'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool',
'default' => '0'
),
'JXBLOG_POSTS_PER_PAGE' => array(
'title' => $this->l('Items per page'),
'desc' => $this->l('How many items will be displayed in listings on the front page?'),
'validation' => 'isInt',
'type' => 'text',
'default' => '6'
)
),
'submit' => array(
'title' => $this->l('Save')
)
)
);
}
}

View File

@@ -0,0 +1,402 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class AdminJXBlogPostsController extends ModuleAdminController
{
public $categories = false;
protected $helper;
public function __construct()
{
$this->table = 'jxblog_post';
$this->list_id = $this->table;
$this->identifier = 'id_jxblog_post';
$this->className = 'JXBlogPost';
$this->module = $this;
$this->lang = true;
$this->bootstrap = true;
$this->languages = Language::getLanguages(false);
$this->default_language = Configuration::get('PS_LANG_DEFAULT');
$this->context = Context::getContext();
$this->_defaultOrderBy = 'a.id_jxblog_post';
$this->_defaultOrderWay = 'ASC';
$this->_default_pagination = 10;
$this->_pagination = array(10, 20, 50, 100);
$this->_orderBy = Tools::getValue($this->table.'Orderby');
$this->_orderWay = Tools::getValue($this->table.'Orderway');
$this->imageDir = '../modules/jxblog/img/p/';
$this->translator = Context::getContext()->getTranslator();
$this->bulk_actions = array(
'delete' => array(
'text' => $this->l('Delete selected'),
'icon' => 'icon-trash',
'confirm' => $this->l('Delete selected items?')
)
);
$this->fields_list = array(
'id_jxblog_post' => array(
'title' => $this->l('ID Post'),
'width' => 50,
'type' => 'text',
'search' => true,
'orderby' => true
),
'image' => array(
'title' => $this->l('Image'),
'image' => $this->imageDir,
'width' => 150,
'align' => 'center',
'orderby' => false,
'filter' => false,
'search' => false
),
'name' => array(
'title' => $this->l('Name'),
'width' => 300,
'type' => 'text',
'search' => true,
'orderby' => true,
'lang' => true,
'filter_key' => 'b!name'
),
'category_name' => array(
'title' => $this->l('Default category'),
'width' => 300,
'type' => 'text',
'search' => true,
'orderby' => true,
'lang' => true,
'filter_key' => 'cl!name'
),
'employee_last_name' => array(
'title' => $this->l('Author'),
'width' => 300,
'type' => 'text',
'search' => true,
'orderby' => true,
'lang' => true,
'filter_key' => 'e!firstname'
),
'views' => array(
'title' => $this->l('Views'),
'type' => 'text',
'search' => true,
'orderby' => true,
'lang' => true
),
'date_add' => array(
'title' => $this->l('Date added'),
'width' => 100,
'type' => 'datetime',
'search' => true,
'orderby' => true
),
'date_start' => array(
'title' => $this->l('Posted date'),
'width' => 100,
'type' => 'datetime',
'search' => true,
'orderby' => true
),
'active' => array(
'title' => $this->l('Active'),
'active' => 'status',
'type' => 'bool',
'class' => 'fixed-width-xs',
'align' => 'center',
'ajax' => true,
'orderby' => false
)
);
$this->_join = 'LEFT JOIN `'._DB_PREFIX_.'jxblog_category_lang` cl ON(a.`id_jxblog_category_default` = cl.`id_jxblog_category` AND cl.`id_lang` = '.$this->context->language->id.')';
$this->_join .= ' LEFT JOIN `'._DB_PREFIX_.'employee` e ON(a.`author` = e.`id_employee`)';
$this->_select = 'cl.`name` as `category_name`, CONCAT(e.`lastname`," ",e.`firstname`) as `employee_last_name`';
parent::__construct();
if (!$this->module->active) {
Tools::redirectAdmin($this->context->link->getAdminLink('AdminHome'));
}
$this->helper = new HelperBlog();
}
public function setMedia($isNewTheme = false)
{
$this->context->controller->addJquery();
$this->context->controller->addJqueryUI('ui.widget');
$this->context->controller->addJqueryPlugin(array('tagify'));
$this->context->controller->addJs($this->module->modulePath.'views/js/jxblog_admin.js');
$this->context->controller->addCss($this->module->modulePath.'views/css/jxblog_admin.css');
parent::setMedia($isNewTheme);
}
public function renderList()
{
$this->addRowAction('edit');
$this->addRowAction('delete');
return parent::renderList();
}
public function initContent()
{
if (!$this->categories = JXBlogCategory::getAllCategoriesWithInfo()) {
return $this->errors[] = $this->l('There are no categories in the blog. To create a post you need to create at least one category before.');
}
return parent::initContent();
}
public function renderForm()
{
$categoriesTree = $this->helper->buildTree();
$image = false;
$thumb = false;
if (Tools::getIsset('id_jxblog_post') && $id_jxblog_post = Tools::getValue('id_jxblog_post')) {
if (file_exists($this->module->modulePath.'img/p/'.$id_jxblog_post.'.jpg')) {
$image = '<img class="imgm img-thumbnail" src="'.$this->module->_link.'img/p/'.$id_jxblog_post.'.jpg" width="300" />';
}
}
if (isset($id_jxblog_post)) {
if (file_exists($this->module->modulePath.'img/pt/'.$id_jxblog_post.'.jpg')) {
$thumb = '<img class="imgm img-thumbnail" src="'.$this->module->_link.'img/pt/'.$id_jxblog_post.'.jpg" width="300" />';
}
}
if (Tools::getIsset('id_jxblog_post') && $id_jxblog_post = Tools::getValue('id_jxblog_post')) {
$post = new JXBlogPost($id_jxblog_post);
}
$defaultList = array();
foreach ($this->categories as $key => $category) {
if ($category['id_jxblog_category'] > 1) {
$defaultList[$key]['id'] = $category['id_jxblog_category'];
$defaultList[$key]['name'] = $category['name'];
}
}
$this->fields_form = array(
'input' => array(
array(
'type' => 'text',
'required' => true,
'class' => 'copy2friendlyUrl',
'label' => $this->l('Post name'),
'hint' => $this->l('Invalid characters: &lt;&gt;;=#{}'),
'desc' => $this->l('Enter the blog post name'),
'name' => 'name',
'lang' => true,
'col' => 4
),
array(
'type' => 'text',
'hint' => $this->l('Only letters, numbers, underscore (_) and the minus (-) character are allowed.'),
'label' => $this->l('Friendly URL'),
'name' => 'link_rewrite',
'required' => true,
'desc' => $this->l('Enter the blog post friendly URL. Will be used as a link to the post in the "Friendly URL" mode'),
'lang' => true,
'col' => 3
),
array(
'type' => 'textarea',
'label' => $this->l('Short description'),
'name' => 'short_description',
'desc' => $this->l('Enter the post short description'),
'lang' => true,
'col' => 6,
'autoload_rte' => true
),
array(
'type' => 'textarea',
'label' => $this->l('Full description'),
'name' => 'description',
'desc' => $this->l('Enter the post full description'),
'lang' => true,
'col' => 6,
'autoload_rte' => true
),
array(
'type' => 'text',
'hint' => $this->l('Only letters, numbers, underscore (_) and the minus (-) character are allowed.'),
'label' => $this->l('Meta Keywords'),
'name' => 'meta_keyword',
'desc' => $this->l('Enter Your Post Meta Keywords. Separated by comma(,)'),
'lang' => true,
'col' => 6
),
array(
'type' => 'textarea',
'label' => $this->l('Meta Description'),
'name' => 'meta_description',
'desc' => $this->l('Enter the post meta description'),
'lang' => true,
'col' => 6,
'autoload_rte' => false
),
array(
'type' => 'file',
'label' => $this->l('Post image'),
'name' => 'image',
'display_image' => true,
'image' => $image ? $image : false,
'desc' => $this->l('Only .jpg images are allowed')
),
array(
'type' => 'file',
'label' => $this->l('Post thumb'),
'name' => 'thumbnail',
'display_image' => true,
'image' => $thumb ? $thumb : false,
'desc' => $this->l('Only .jpg images are allowed')
),
array(
'type' => 'switch',
'label' => $this->l('Status'),
'name' => 'active',
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Enabled')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('Disabled')
)
)
),
array(
'type' => 'select',
'label' => $this->l('Default category'),
'name' => 'id_jxblog_category_default',
'required' => true,
'options' => array(
'query' => $defaultList,
'id' => 'id',
'name' => 'name'
)
),
array(
'type' => 'categories',
'label' => $this->l('Associated categories'),
'name' => 'jxcategoryBox',
'tree' => array(
'id' => 'blog-categories-tree',
'selected_categories' => isset($post) ? $post->getAssociatedCategories() : array(),
'root_category' => 1,
'set_data' => $categoriesTree,
'use_search' => true,
'use_checkbox' => true
)
),
array(
'type' => 'tags',
'name' => 'tags',
'label' => $this->l('Post tags'),
'lang' => true,
'hint' => $this->l('To add "tags," click in the field, write something, and then press "Enter."').'&nbsp;'.$this->l('Forbidden characters:').' <>;=#{}'
),
array(
'type' => 'datetime',
'name' => 'date_start',
'label' => $this->l('Publishing date'),
'desc' => $this->l('Set the date if you want to delay the article publishing.')
)
),
'submit' => array(
'title' => $this->l('Save'),
'class' => 'button pull-right btn btn-default'
)
);
$extraData = array_values(Hook::exec('displayJxblogPostExtra', array('post' => isset($post) ? $post : false), null, true));
// add all necessary data from related modules
if ($extraData) {
foreach ($extraData as $extra) {
$extraFields = $extra['fields'];
$extraValues = $extra['values'];
foreach ($extraFields as $filed) {
$this->fields_form['input'][] = $filed;
}
foreach ($extraValues as $key => $filed) {
$this->fields_value[$key] = $filed;
}
}
}
$this->fields_value['tags'] = isset($post) ? $post->getAdminPostTags() : false;
if (!($JXBlogPost = $this->loadObject(true))) {
return;
}
return parent::renderForm();
}
public function ajaxProcessSearchPosts()
{
$excludeIds = array();
$exclude = explode(',', Tools::getValue('excludeIds'));
foreach ($exclude as $item) {
if ($item) {
$excludeIds[] = $item;
}
}
$posts = JXBlogPost::searchPostsLive(Tools::getValue('q'), $this->context->language->id, Tools::getValue('limit'), $excludeIds);
if ($posts) {
die(implode("\n", $posts));
}
}
public function ajaxProcessStatusjxblogPost()
{
if (!$id_post = (int)Tools::getValue('id_jxblog_post')) {
die(json_encode(
array(
'success' => false,
'error' => true,
'text' => $this->l('Failed to update the status')
)
));
} else {
$post = new JXBlogPost((int)$id_post);
if (Validate::isLoadedObject($post)) {
$post->active = $post->active == 1 ? 0 : 1;
$post->save() ?
die(json_encode(
array(
'success' => true,
'text' => $this->l('The status has been updated successfully')
)
)) :
die(json_encode(
array(
'success' => false,
'error' => true,
'text' => $this->l('Failed to update the status')
)
));
}
}
}
}

View File

@@ -0,0 +1,9 @@
drwxr-xr-x 2 30094 users 9 Oct 6 10:16 .
drwxr-xr-x 4 30094 users 4 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 2666 Aug 31 2021 author.php
-rw-r--r-- 1 30094 users 2778 Aug 31 2021 blog.php
-rw-r--r-- 1 30094 users 2331 Aug 31 2021 categories.php
-rw-r--r-- 1 30094 users 3697 Aug 31 2021 category.php
-rw-r--r-- 1 30094 users 2903 Aug 31 2021 post.php
-rw-r--r-- 1 30094 users 4849 Aug 31 2021 search.php
-rw-r--r-- 1 30094 users 2598 Aug 31 2021 tag.php

View File

@@ -0,0 +1,79 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class JxblogAuthorModuleFrontController extends ModuleFrontController
{
public $pagename = 'author';
public $author;
public $page = 1;
public $itemPerPage = 6;
public function __construct()
{
if (Tools::getIsset('page') && $page = Tools::getValue('page')) {
$this->page = $page;
}
parent::__construct();
$this->itemPerPage = Configuration::get('JXBLOG_POSTS_PER_PAGE');
$this->author = new Employee(Tools::getValue('author'));
}
public function initContent()
{
parent::initContent();
$pagination = false;
$posts = false;
if ($this->author) {
$posts = JXBlogPost::getPostsByAuthor($this->author->id, $this->context->language->id, $this->page, $this->itemPerPage);
$pagination = $this->module->buildPagination(
'apagination',
JXBlogPost::countPostsByAuthor($this->author->id),
$this->page,
$this->itemPerPage,
$this->author->id,
''
);
}
$this->context->smarty->assign(
array(
'author' => $this->author,
'posts' => $posts,
'pagination' => $pagination,
'displayViews' => Configuration::get('JXBLOG_DISPLAY_POST_VIEWS'),
'displayAuthor' => Configuration::get('JXBLOG_DISPLAY_POST_AUTHOR')
)
);
$this->setTemplate('module:jxblog/views/templates/front/author.tpl');
}
public function getBreadcrumbLinks()
{
$link = new Link();
$breadcrumb = parent::getBreadcrumbLinks();
$breadcrumb['links'][] = array('title' => $this->module->translator('all_categories'), 'url' => $link->getModuleLink('jxblog', 'categories'));
$breadcrumb['links'][] = array('title' => $this->author->firstname.' '.$this->author->lastname, 'url' => $link->getModuleLink('jxblog', 'author', array('author' => $this->author->id)));
return $breadcrumb;
}
}

View File

@@ -0,0 +1,86 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class JxblogBlogModuleFrontController extends ModuleFrontController
{
public $pagename = 'blog';
public $itemPerPage = 1;
public $page = 1;
public function __construct()
{
// if this page is terned off redirect to default page
if (!Configuration::get('JXBLOG_DISPLAY_BLOG_PAGE')) {
$link = new Link();
Tools::redirect($link->getModuleLink('jxblog', 'categories'));
}
if (Tools::getIsset('page') && $page = Tools::getValue('page')) {
$this->page = $page;
}
parent::__construct();
$this->itemPerPage = Configuration::get('JXBLOG_POSTS_PER_PAGE');
}
public function initContent()
{
parent::initContent();
$pagination = false;
$categories = JXBlogCategory::getAllFrontCategories(
2,
$this->context->language->id,
$this->context->shop->id,
$this->context->customer->id_default_group,
1,
1000
);
$posts = JXBlogPost::getAllPosts($this->context->language->id, $this->context->shop->id, $this->context->customer->id_default_group, $this->page, $this->itemPerPage);
if ($posts) {
$pagination = $this->module->buildPagination(
'bpagination',
JXBlogPost::countAllPosts(
2,
$this->context->shop->id,
$this->context->customer->id_default_group
),
$this->page,
$this->itemPerPage
);
}
$this->context->smarty->assign(
array(
'categories' => $categories,
'posts' => $posts,
'pagination' => $pagination
)
);
$this->setTemplate('module:jxblog/views/templates/front/blog.tpl');
}
public function getBreadcrumbLinks()
{
$link = new Link();
$breadcrumb = parent::getBreadcrumbLinks();
$breadcrumb['links'][] = array('title' => $this->module->translator('blog'), 'url' => $link->getModuleLink('jxblog', 'blog'));
return $breadcrumb;
}
}

View File

@@ -0,0 +1,80 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class JxblogCategoriesModuleFrontController extends ModuleFrontController
{
public $pagename = 'categories';
public $itemPerPage = 6;
public $page = 1;
public function __construct()
{
if (Tools::getIsset('page') && $page = Tools::getValue('page')) {
$this->page = $page;
}
parent::__construct();
$this->itemPerPage = Configuration::get('JXBLOG_POSTS_PER_PAGE');
}
public function initContent()
{
parent::initContent();
$pagination = false;
$categories = JXBlogCategory::getAllFrontCategories(
2,
$this->context->language->id,
$this->context->shop->id,
$this->context->customer->id_default_group,
$this->page,
$this->itemPerPage
);
if ($categories) {
$pagination = $this->module->buildPagination(
'cpagination',
JXBlogCategory::countFrontCategories(
2,
$this->context->shop->id,
$this->context->customer->id_default_group
),
$this->page,
$this->itemPerPage
);
}
$this->context->smarty->assign(
array(
'categories' => $categories,
'pagination' => $pagination
)
);
$this->setTemplate('module:jxblog/views/templates/front/categories.tpl');
}
public function getBreadcrumbLinks()
{
$breadcrumb = parent::getBreadcrumbLinks();
$breadcrumb['links'][] = array('title' => $this->module->translator('all_categories'), 'url' => '');
return $breadcrumb;
}
}

View File

@@ -0,0 +1,102 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class JxblogCategoryModuleFrontController extends ModuleFrontController
{
public $pagename = 'category';
public $category;
public $page = 1;
public $itemPerPage = 6;
public $helper;
public function __construct()
{
if (Tools::getIsset('page') && $page = Tools::getValue('page')) {
$this->page = $page;
}
parent::__construct();
$this->itemPerPage = Configuration::get('JXBLOG_POSTS_PER_PAGE');
$this->category = new JXBlogCategory(Tools::getValue('id_jxblog_category'), $this->context->language->id);
$this->helper = new HelperBlog();
$this->helper->buildBreadCrumbs($this->category->id_jxblog_category, 2);
}
public function initContent()
{
parent::initContent();
$pagination = false;
$posts = false;
$category = JXBlogCategory::getCategory($this->category->id, $this->context->language->id, $this->context->shop->id, $this->context->customer->id_default_group)[0];
$subCategories = JXBlogCategory::getSubCategories(
$this->category->id,
$this->context->language->id,
$this->context->shop->id,
$this->context->customer->id_default_group
);
if ($category) {
$posts = JXBlogPost::getPostsByCategory($this->category->id, $this->context->language->id, $this->page, $this->itemPerPage);
$pagination = $this->module->buildPagination(
'pagination',
JXBlogPost::countPostsByCategory($this->category->id),
$this->page,
$this->itemPerPage,
$this->category->id,
$this->category->link_rewrite
);
}
$this->context->smarty->assign(
array(
'category' => $category,
'sub_categories' => $subCategories,
'posts' => $posts,
'pagination' => $pagination,
'displayViews' => Configuration::get('JXBLOG_DISPLAY_POST_VIEWS'),
'displayAuthor' => Configuration::get('JXBLOG_DISPLAY_POST_AUTHOR')
)
);
$this->setTemplate('module:jxblog/views/templates/front/category.tpl');
}
public function getBreadcrumbLinks()
{
$link = new Link();
$breadcrumb = parent::getBreadcrumbLinks();
$breadcrumb['links'][] = array('title' => $this->module->translator('all_categories'), 'url' => $link->getModuleLink('jxblog', 'categories'));
foreach ($this->helper->getBreadCrumbs() as $item) {
// exclude home and root categories
$breadcrumb['links'][] = array(
'title' => $item['name'],
'url' => $link->getModuleLink(
'jxblog',
'category',
array(
'id_jxblog_category' => $item['id_jxblog_category'],
'rewrite' => $item['link_rewrite']
)
)
);
}
return $breadcrumb;
}
}

View File

@@ -0,0 +1,79 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class JxblogPostModuleFrontController extends ModuleFrontController
{
public $pagename = 'jxblogpost';
public $post;
protected $helper;
public function __construct()
{
$this->helper = new HelperBlog();
parent::__construct();
$this->post = new JXBlogPost(Tools::getValue('id_jxblog_post'), $this->context->language->id);
$this->helper->buildBreadCrumbs($this->post->id_jxblog_category_default, 2);
}
public function initContent()
{
parent::initContent();
JXBlogPost::postViewed($this->post->id);
$post = JXBlogPost::getPost($this->post->id, $this->context->language->id, $this->context->shop->id, $this->context->customer->id_default_group);
if ($post) {
$post = $post[0];
}
$this->context->smarty->assign(
array(
'post' => $post,
'tags' => JXBlogPost::getPostTags($this->post->id, $this->context->language->id),
'displayViews' => Configuration::get('JXBLOG_DISPLAY_POST_VIEWS'),
'displayAuthor' => Configuration::get('JXBLOG_DISPLAY_POST_AUTHOR')
)
);
$this->setTemplate('module:jxblog/views/templates/front/post.tpl');
}
public function getBreadcrumbLinks()
{
$link = new Link();
$breadcrumb = parent::getBreadcrumbLinks();
$breadcrumb['links'][] = array('title' => $this->module->translator('all_categories'), 'url' => $link->getModuleLink('jxblog', 'categories'));
foreach ($this->helper->getBreadCrumbs() as $item) {
// exclude home and root categories
$breadcrumb['links'][] = array(
'title' => $item['name'],
'url' => $link->getModuleLink(
'jxblog',
'category',
array(
'id_jxblog_category' => $item['id_jxblog_category'],
'rewrite' => $item['link_rewrite']
)
)
);
}
$breadcrumb['links'][] = array('title' => $this->post->name, 'url' => $link->getModuleLink('jxblog', 'post', array('id_jxblog_post' => $this->post->id, 'rewrite' => $this->post->link_rewrite)));
return $breadcrumb;
}
}

View File

@@ -0,0 +1,138 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class JxblogSearchModuleFrontController extends ModuleFrontController
{
public $pagename = 'search';
public $query;
public $category;
public $page = 1;
public $itemPerPage = 6;
public function __construct()
{
if (Tools::getIsset('page') && $page = Tools::getValue('page')) {
$this->page = $page;
}
parent::__construct();
$this->itemPerPage = Configuration::get('JXBLOG_POSTS_PER_PAGE');
$this->query = Tools::getValue('blog_search_query');
$this->category = Tools::getValue('search_blog_categories');
}
public function initContent()
{
$query = Tools::replaceAccentedChars(urldecode(Tools::getValue('q')));
if (Tools::getValue('ajax')) {
$this->getAjaxSearch($query);
} else {
parent::initContent();
$pagination = false;
$posts = false;
if ($this->query) {
$posts = JXBlogPost::search(
$this->query,
$this->category,
$this->context->language->id,
$this->context->shop->id,
$this->context->customer->id_default_group,
$this->page,
$this->itemPerPage
);
$pagination = $this->module->buildPagination(
'spagination',
JXBlogPost::countPostsBySearch(
$this->query,
$this->category,
$this->context->language->id,
$this->context->shop->id,
$this->context->customer->id_default_group
),
$this->page,
$this->itemPerPage,
'',
''
);
$currentCategoryName = '';
if ($this->category) {
$currentCategory = new JXBlogCategory($this->category, $this->context->language->id);
$currentCategoryName = $currentCategory->name;
}
}
$this->context->smarty->assign(
array(
'blog_search_query' => $this->query,
'posts' => $posts,
'pagination' => $pagination,
'active_blog_category' => $currentCategoryName,
'displayViews' => Configuration::get('JXBLOG_DISPLAY_POST_VIEWS'),
'displayAuthor' => Configuration::get('JXBLOG_DISPLAY_POST_AUTHOR')
)
);
$this->setTemplate('module:jxblog/views/templates/front/search.tpl');
}
}
public function getBreadcrumbLinks()
{
$link = new Link();
$breadcrumb = parent::getBreadcrumbLinks();
$breadcrumb['links'][] = array('title' => $this->module->translator('all_categories'), 'url' => $link->getModuleLink('jxblog', 'categories'));
return $breadcrumb;
}
protected function getAjaxSearch($query)
{
$id_category = (int)Tools::getValue('category');
$posts = JXBlogPost::search(
$query,
$id_category,
$this->context->language->id,
$this->context->shop->id,
$this->context->customer->id_default_group,
1,
1000
);
$output = array();
if (count($posts)) {
$jxsearch = new Jxsearch();
$link = new Link();
foreach ($posts as $post) {
$this->context->smarty->assign('post', array(
'info' => $post,
'url' => $link->getModuleLink('jxblog', 'post', array('id_jxblog_post' => $post['id_jxblog_post'], 'rewrite' => $post['link_rewrite'])),
));
$output[] = $jxsearch->display($jxsearch->getLocalPath(), '/views/templates/hook/_items/row-blog.tpl');
}
}
if (!count($output)) {
die(json_encode(array('empty' => $this->l('No post found'))));
}
$total = count($output);
die(json_encode(array('result' => $output, 'total' => $total)));
}
}

View File

@@ -0,0 +1,78 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class JxblogTagModuleFrontController extends ModuleFrontController
{
public $pagename = 'tag';
public $tag;
public $page = 1;
public $itemPerPage = 6;
public function __construct()
{
if (Tools::getIsset('page') && $page = Tools::getValue('page')) {
$this->page = $page;
}
parent::__construct();
$this->itemPerPage = Configuration::get('JXBLOG_POSTS_PER_PAGE');
$this->tag = new JXBlogTag(Tools::getValue('id_jxblog_tag'));
}
public function initContent()
{
parent::initContent();
$pagination = false;
$posts = false;
if ($this->tag) {
$posts = JXBlogPost::getPostsByTag($this->tag->id, $this->context->language->id, $this->page, $this->itemPerPage);
$pagination = $this->module->buildPagination(
'tpagination',
JXBlogPost::countPostsByTag($this->tag->id),
$this->page,
$this->itemPerPage,
$this->tag->id,
''
);
}
$this->context->smarty->assign(
array(
'tag' => $this->tag,
'posts' => $posts,
'pagination' => $pagination,
'displayViews' => Configuration::get('JXBLOG_DISPLAY_POST_VIEWS'),
'displayAuthor' => Configuration::get('JXBLOG_DISPLAY_POST_AUTHOR')
)
);
$this->setTemplate('module:jxblog/views/templates/front/tag.tpl');
}
public function getBreadcrumbLinks()
{
$link = new Link();
$breadcrumb = parent::getBreadcrumbLinks();
$breadcrumb['links'][] = array('title' => $this->module->translator('all_categories'), 'url' => $link->getModuleLink('jxblog', 'categories'));
$breadcrumb['links'][] = array('title' => $this->tag->tag, 'url' => $link->getModuleLink('jxblog', 'tag', array('id_jxblog_tag' => $this->tag->id)));
return $breadcrumb;
}
}

View File

@@ -0,0 +1,3 @@
drwxr-xr-x 2 30094 users 3 Oct 6 10:16 .
drwxr-xr-x 9 30094 users 16 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 3767 Aug 31 2021 HelperBlog.php

View File

@@ -0,0 +1,102 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class HelperBlog
{
protected $breadCrumbs = array();
public function buildTree($id_category = 1)
{
$rootCategories = array();
$rootCategories[$id_category] = JXBlogCategory::getChildrenCategories($id_category);
$tree = $this->fillTree($rootCategories, $id_category);
return $tree;
}
public function buildFrontTree($id_category, $group, $active = false)
{
if (!JXBlogCategory::getCategory($id_category, Context::getContext()->language->id, Context::getContext()->shop->id, $group)) {
return array();
}
$rootCategories = array();
$tree = array();
$rootCategories[$id_category] = JXBlogCategory::getChildrenCategories($id_category, $group, $active);
$category = JXBlogCategory::getCategoryShortInfo($id_category, Context::getContext()->language->id);
// at first add top category and then create its children tree
$tree[$id_category] = array(
'id_category' => $category['id_jxblog_category'],
'name' => $category['name'],
'link_rewrite' => $category['link_rewrite']
);
$tree[$id_category]['children'] = $this->fillTree($rootCategories, $id_category, $group, $active);
return $tree;
}
private function fillTree(&$categories, $rootCategoryId, $group = false, $active = false)
{
$tree = array();
$rootCategoryId = (int) $rootCategoryId;
foreach ($categories[$rootCategoryId] as $category) {
$categoryId = (int)$category['id_category'];
$tree[$categoryId] = $category;
if ($categoryChildren = JXBlogCategory::getChildrenCategories($categoryId, $group, $active)) {
foreach ($categoryChildren as $child) {
$childId = (int) $child['id_category'];
if (!array_key_exists('children', $tree[$categoryId])) {
$tree[$categoryId]['children'] = array($childId => $child);
} else {
$tree[$categoryId]['children'][$childId] = $child;
}
$categories[$childId] = array($child);
}
foreach ($tree[$categoryId]['children'] as $childId => $child) {
$subtree = $this->fillTree($categories, $childId, $group, $active);
foreach ($subtree as $subcategoryId => $subcategory) {
$tree[$categoryId]['children'][$subcategoryId] = $subcategory;
}
}
}
}
return $tree;
}
public function buildBreadCrumbs($id_category, $id_category_min = 1)
{
$category = JXBlogCategory::getCategoryShortInfo($id_category, Context::getContext()->language->id);
$this->breadCrumbs[$category['id_jxblog_category']] = $category;
if ($category['id_parent_category'] > $id_category_min) {
$this->buildBreadCrumbs($category['id_parent_category'], $id_category_min);
}
}
public function getBreadCrumbs()
{
return array_reverse($this->breadCrumbs);
}
}

View File

@@ -0,0 +1,6 @@
drwxr-xr-x 6 30094 users 6 Oct 6 10:16 .
drwxr-xr-x 9 30094 users 16 Oct 6 10:16 ..
drwxr-xr-x 2 30094 users 4 Oct 6 10:16 c
drwxr-xr-x 2 30094 users 4 Oct 6 10:16 ct
drwxr-xr-x 2 30094 users 5 Oct 6 10:16 p
drwxr-xr-x 2 30094 users 5 Oct 6 10:16 pt

View File

@@ -0,0 +1,4 @@
drwxr-xr-x 2 30094 users 4 Oct 6 10:16 .
drwxr-xr-x 6 30094 users 6 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 386275 Aug 31 2021 3.jpg
-rw-r--r-- 1 30094 users 192068 Aug 31 2021 4.jpg

BIN
modules/jxblog/img/c/3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 KiB

BIN
modules/jxblog/img/c/4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

View File

@@ -0,0 +1,4 @@
drwxr-xr-x 2 30094 users 4 Oct 6 10:16 .
drwxr-xr-x 6 30094 users 6 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 386275 Aug 31 2021 3.jpg
-rw-r--r-- 1 30094 users 192068 Aug 31 2021 4.jpg

BIN
modules/jxblog/img/ct/3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 KiB

BIN
modules/jxblog/img/ct/4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

View File

@@ -0,0 +1,5 @@
drwxr-xr-x 2 30094 users 5 Oct 6 10:16 .
drwxr-xr-x 6 30094 users 6 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 272014 Aug 31 2021 1.jpg
-rw-r--r-- 1 30094 users 192068 Aug 31 2021 2.jpg
-rw-r--r-- 1 30094 users 386275 Aug 31 2021 3.jpg

BIN
modules/jxblog/img/p/1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

BIN
modules/jxblog/img/p/2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

BIN
modules/jxblog/img/p/3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 KiB

View File

@@ -0,0 +1,5 @@
drwxr-xr-x 2 30094 users 5 Oct 6 10:16 .
drwxr-xr-x 6 30094 users 6 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 272014 Aug 31 2021 1.jpg
-rw-r--r-- 1 30094 users 192068 Aug 31 2021 2.jpg
-rw-r--r-- 1 30094 users 386275 Aug 31 2021 3.jpg

BIN
modules/jxblog/img/pt/1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

BIN
modules/jxblog/img/pt/2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

BIN
modules/jxblog/img/pt/3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 KiB

32
modules/jxblog/index.php Normal file
View File

@@ -0,0 +1,32 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

449
modules/jxblog/jxblog.php Normal file
View File

@@ -0,0 +1,449 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
use PrestaShop\PrestaShop\Core\Module\WidgetInterface;
include_once(_PS_MODULE_DIR_.'jxblog/src/JXBlogRepository.php');
include_once(_PS_MODULE_DIR_.'jxblog/src/TabManager.php');
include_once(_PS_MODULE_DIR_.'jxblog/helper/HelperBlog.php');
include_once(_PS_MODULE_DIR_.'jxblog/classes/JXBlogCategory.php');
include_once(_PS_MODULE_DIR_.'jxblog/classes/JXBlogPost.php');
include_once(_PS_MODULE_DIR_.'jxblog/classes/JXBlogTag.php');
include_once(_PS_MODULE_DIR_.'jxblog/classes/JXBlogImage.php');
include_once(_PS_MODULE_DIR_.'jxblog/classes/JXBlogImageManager.php');
class Jxblog extends Module implements WidgetInterface
{
public $repository;
public $mainTab = array();
public $tabs = array();
public $languages;
public $modulePath;
public $_link;
public $imagesAutoRegenerate;
public $imageTypes;
private $breadcrumbsTranslations;
public function __construct()
{
$this->name = 'jxblog';
$this->tab = 'content_management';
$this->version = '1.1.2';
$this->author = 'Zemez (Alexander Grosul)';
$this->need_instance = 1;
$this->controllers = array('blog', 'author', 'categories', 'category', 'post', 'search', 'tag');
$this->bootstrap = true;
parent::__construct();
$this->modulePath = $this->local_path;
$this->_link = $this->_path;
$this->displayName = $this->l('JX Blog');
$this->description = $this->l('The best blog-extension for Prestashop platform.');
$this->confirmUninstall = $this->l('Are you sure that you want to delete the module? All related data will be deleted forever!');
$this->ps_versions_compliancy = array('min' => '1.7', 'max' => _PS_VERSION_);
$this->languages = Language::getLanguages(true);
$this->defaultLanguage = new Language(Configuration::get('PS_LANG_DEFAULT'));
$this->repository = new JXBlogRepository(Db::getInstance(), $this->context->shop);
$this->tabManager = new TabManager();
$this->imageTypes = array(
'default' => array('default'),
'category' => array('c/', 'category'),
'category_thumb' => array('ct/', 'category_thumb'),
'post' => array('p/', 'post'),
'post_thumb' => array('pt/', 'post_thumb'),
'user' => array('u/', 'user')
);
$this->imagesAutoRegenerate = Configuration::get('JXBLOG_IMAGES_AUTO_REGENERATION');
$this->breadcrumbsTranslations = array(
'all_categories' => $this->l('Blog categories'),
'blog' => $this->l('Blog')
);
}
public function install()
{
return $this->tabManager->installTabs() &&
parent::install() &&
$this->registerHook('header') &&
$this->registerHook('backOfficeHeader') &&
$this->registerHook('moduleRoutes') &&
$this->repository->createTables() &&
$this->setSettings() &&
$this->setFixtures();
}
public function uninstall()
{
// use this hook to delete all related module which are not useful after this module deleting
Hook::exec('actionJXBlogBeforeModuleDelete');
return $this->repository->dropTables() &&
$this->removeSettings() &&
$this->clearAllImages() &&
parent::uninstall() &&
$this->tabManager->removeTab();
}
public function setFixtures()
{
$result = true;
// add root category
$root = new JXBlogCategory();
$root->id_parent_category = 0;
$root->active = 1;
$root->position = 0;
foreach (Language::getLanguages(false) as $language) {
$root->name[$language['id_lang']] = $this->l('Root');
$root->link_rewrite[$language['id_lang']] = 'root';
}
$result &= $root->add();
// add home category
$home = new JXBlogCategory();
$home->id_parent_category = 1;
$home->active = 1;
$home->position = 0;
foreach (Language::getLanguages(false) as $language) {
$home->name[$language['id_lang']] = $this->l('Home');
$home->link_rewrite[$language['id_lang']] = 'home';
}
$result &= $home->add();
return $result;
}
public function setSettings()
{
Configuration::updateValue('JXBLOG_IMAGES_AUTO_REGENERATION', 1);
Configuration::updateValue('JXBLOG_DISPLAY_BLOG_PAGE', 0);
Configuration::updateValue('JXBLOG_DISPLAY_PRODUCTS_ON_BLOG_PAGE', 1);
Configuration::updateValue('JXBLOG_DISPLAY_POST_AUTHOR', 1);
Configuration::updateValue('JXBLOG_DISPLAY_POST_VIEWS', 1);
Configuration::updateValue('JXBLOG_POSTS_PER_PAGE', 6);
return true;
}
public function removeSettings()
{
Configuration::deleteByName('JXBLOG_IMAGES_AUTO_REGENERATION');
Configuration::deleteByName('JXBLOG_DISPLAY_POST_AUTHOR');
Configuration::deleteByName('JXBLOG_DISPLAY_POST_VIEWS');
Configuration::deleteByName('JXBLOG_POSTS_PER_PAGE');
return true;
}
protected function clearAllImages()
{
$imagesList = array();
$path = $this->modulePath.'/img/';
foreach ($this->imageTypes as $type => $imageType) {
if ($type != 'default') {
$path = $this->modulePath.'/img/'.$imageType[0];
}
if ($images = Tools::scandir($path, 'jpg')) {
foreach ($images as $image) {
array_push($imagesList, $path.$image);
}
}
}
if ($imagesList) {
$imageManager = new JXBlogImageManager($this);
return $imageManager->removeImagesByList($imagesList);
}
return true;
}
public function hookModuleRoutes()
{
return array(
'module-jxblog-blog' => array(
'controller' => 'blog',
'rule' => 'blog',
'keywords' => array(),
'params' => array(
'fc' => 'module',
'module' => 'jxblog',
)
),
'module-jxblog-bpagination' => array(
'controller' => 'blog',
'rule' => 'blog/page/{page}',
'keywords' => array(
'page' => array('regexp' => '[_a-zA-Z0-9-\pL]*', 'param' => 'page'),
),
'params' => array(
'fc' => 'module',
'module' => 'jxblog',
)
),
'module-jxblog-categories' => array(
'controller' => 'categories',
'rule' => 'blog/categories',
'keywords' => array(),
'params' => array(
'fc' => 'module',
'module' => 'jxblog',
)
),
'module-jxblog-cpagination' => array(
'controller' => 'categories',
'rule' => 'blog/categories/page/{page}',
'keywords' => array(
'page' => array('regexp' => '[_a-zA-Z0-9-\pL]*', 'param' => 'page'),
),
'params' => array(
'fc' => 'module',
'module' => 'jxblog',
)
),
'module-jxblog-category' => array(
'controller' => 'category',
'rule' => 'blog/category/{id_jxblog_category}/{rewrite}',
'keywords' => array(
'id_jxblog_category' => array('regexp' => '[0-9]+', 'param' => 'id_jxblog_category'),
'rewrite' => array('regexp' => '[_a-zA-Z0-9\pL\pS-]*')
),
'params' => array(
'fc' => 'module',
'module' => 'jxblog',
)
),
'module-jxblog-tag' => array(
'controller' => 'tag',
'rule' => 'blog/tag/{id_jxblog_tag}',
'keywords' => array(
'id_jxblog_tag' => array('regexp' => '[0-9]+', 'param' => 'id_jxblog_tag')
),
'params' => array(
'fc' => 'module',
'module' => 'jxblog',
)
),
'module-jxblog-tpagination' => array(
'controller' => 'tag',
'rule' => 'blog/tag/{id_jxblog_tag}/page/{page}',
'keywords' => array(
'id_jxblog_tag' => array('regexp' => '[0-9]+', 'param' => 'id_jxblog_tag'),
'page' => array('regexp' => '[_a-zA-Z0-9-\pL]*', 'param' => 'page'),
),
'params' => array(
'fc' => 'module',
'module' => 'jxblog',
)
),
'module-jxblog-author' => array(
'controller' => 'author',
'rule' => 'blog/author/{author}',
'keywords' => array(
'author' => array('regexp' => '[0-9]+', 'param' => 'author')
),
'params' => array(
'fc' => 'module',
'module' => 'jxblog',
)
),
'module-jxblog-apagination' => array(
'controller' => 'author',
'rule' => 'blog/author/{author}/page/{page}',
'keywords' => array(
'author' => array('regexp' => '[0-9]+', 'param' => 'author'),
'page' => array('regexp' => '[_a-zA-Z0-9-\pL]*', 'param' => 'page'),
),
'params' => array(
'fc' => 'module',
'module' => 'jxblog',
)
),
'module-jxblog-pagination' => array(
'controller' => 'category',
'rule' => 'blog/category/{id_jxblog_category}/{rewrite}/page/{page}',
'keywords' => array(
'id_jxblog_category' => array('regexp' => '[0-9]+', 'param' => 'id_jxblog_category'),
'rewrite' => array('regexp' => '[_a-zA-Z0-9\pL\pS-]*'),
'page' => array('regexp' => '[_a-zA-Z0-9-\pL]*', 'param' => 'page'),
),
'params' => array(
'fc' => 'module',
'module' => 'jxblog',
)
),
'module-jxblog-post' => array(
'controller' => 'post',
'rule' => 'blog/post/{id_jxblog_post}/{rewrite}',
'keywords' => array(
'id_jxblog_post' => array('regexp' => '[0-9]+', 'param' => 'id_jxblog_post'),
'rewrite' => array('regexp' => '[_a-zA-Z0-9\pL\pS-]*')
),
'params' => array(
'fc' => 'module',
'module' => 'jxblog',
)
),
'module-jxblog-search' => array(
'controller' => 'search',
'rule' => 'blog/search/',
'keywords' => array(
),
'params' => array(
'fc' => 'module',
'module' => 'jxblog',
)
),
);
}
/**
* Used to access blog links from external modules
*
* @param $page
* @param $params
*
* @return string
*/
public function getBlogLink($page, $params)
{
$link = new Link();
return $link->getModuleLink($this->name, $page, $params);
}
public function buildPagination($controller, $totalItems, $page, $itemsPerPage, $id = false, $rewrite = '')
{
if (!$totalItems) {
return false;
}
$link = new Link();
$pagination = array();
$itemShowFrom = 1;
$itemShowTo = $page * $itemsPerPage;
if ($page > 1) {
$itemShowFrom = ($itemsPerPage * ($page - 1)) + 1;
}
if ($itemShowTo > $totalItems) {
$itemShowTo = $totalItems;
}
$params = array();
if ($id) {
$params = array('id_jxblog_category' => $id, 'rewrite' => $rewrite);
}
if ($controller == 'tpagination') {
$params = array('id_jxblog_tag' => $id);
}
if ($controller == 'apagination') {
$params = array('author' => $id);
}
$i = 0;
$totalPages = ceil($totalItems/$itemsPerPage);
$pagination['total'] = $totalItems;
$pagination['from'] = $itemShowFrom;
$pagination['to'] = $itemShowTo;
if ($totalItems > $itemsPerPage) {
$pagination['steps'][$i] = array(
'type' => 'previous',
'url' => $link->getModuleLink(
'jxblog',
$controller,
array_merge(array('page' => $page > 1 ? $page - 1 : $page), $params)
),
'name' => $this->l('Previous'),
'active' => ($page == 1) ? true : false
);
for ($i = &$i; $i < $totalPages; $i++) {
$pagination['steps'][$i + 1]['type'] = 'page';
$pagination['steps'][$i + 1]['url'] = $link->getModuleLink('jxblog', $controller, array_merge(array('page' => $i + 1), $params));
$pagination['steps'][$i + 1]['name'] = $i + 1;
$pagination['steps'][$i + 1]['active'] = ($page == $i + 1) || (!$page && $i == 0) ? true : false;
}
$pagination['steps'][$i + 1] = array(
'type' => 'next',
'url' => $link->getModuleLink(
'jxblog',
$controller,
array_merge(array('page' => $page < $totalPages ? $page + 1 : $page), $params)
),
'name' => $this->l('Next'),
'active' => ($page == $totalPages) ? true : false
);
}
return $pagination;
}
public function hookBackOfficeHeader()
{
if (Tools::getValue('module_name') == $this->name) {
$this->context->controller->addJS($this->_path.'views/js/jxblog_admin.js');
$this->context->controller->addCSS($this->_path.'views/css/jxblog_admin.css');
}
}
public function hookHeader()
{
$this->context->controller->requireAssets(array('font-awesome'));
$this->context->controller->addJS($this->_path.'/views/js/jxblog.js');
$this->context->controller->addCSS($this->_path.'/views/css/jxblog.css');
}
public function getWidgetVariables($hookName = null, array $configuration = [])
{
$link = new Link();
$jxbloglinkurl = $link->getModuleLink($this->name, 'categories');
if (Configuration::get('JXBLOG_DISPLAY_BLOG_PAGE')) {
$jxbloglinkurl = $link->getModuleLink($this->name, 'blog');
}
$this->smarty->assign('jxbloglinkhook', $hookName);
$this->smarty->assign('jxbloglinkurl', $jxbloglinkurl);
}
public function renderWidget($hookName = null, array $configuration = [])
{
if (!$this->isCached('jxbloglink.tpl', $this->getCacheId())) {
$this->getWidgetVariables($hookName, $configuration);
}
return $this->display(
__FILE__,
'views/templates/hook/jxbloglink.tpl',
$this->getCacheId()
);
}
/**
* Temporary workaround to resolve a problem with breadcrumbs items translation
*
* @param $code
*
* @return mixed
*/
public function translator($code)
{
return $this->breadcrumbsTranslations[$code];
}
}

BIN
modules/jxblog/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

BIN
modules/jxblog/logo.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,6 @@
drwxr-xr-x 2 30094 users 6 Oct 6 10:16 .
drwxr-xr-x 9 30094 users 16 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 5643 Aug 31 2021 JXBlogRepository.php
-rw-r--r-- 1 30094 users 2914 Aug 31 2021 JXBlogTabManager.php
-rw-r--r-- 1 30094 users 5290 Aug 31 2021 TabManager.php
-rw-r--r-- 1 30094 users 891 Aug 31 2021 index.php

View File

@@ -0,0 +1,150 @@
<?php
/**
* 2017 Zemz
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class JXBlogRepository
{
private $db;
private $shop;
private $db_prefix;
public function __construct(Db $db, Shop $shop)
{
$this->db = $db;
$this->shop = $shop;
$this->db_prefix = $db->getPrefix();
}
public function createTables()
{
$engine = _MYSQL_ENGINE_;
$success = true;
$this->dropTables();
$queries = array(
"CREATE TABLE IF NOT EXISTS `{$this->db_prefix}jxblog_category`(
`id_jxblog_category` int(10) NOT NULL auto_increment,
`id_parent_category` int(10) NOT NULL,
`active` int(1) NOT NULL,
`position` int(10) NOT NULL,
`date_add` datetime NOT NULL,
`date_upd` datetime NOT NULL,
PRIMARY KEY (`id_jxblog_category`)
) ENGINE=$engine DEFAULT CHARSET=utf8",
"CREATE TABLE IF NOT EXISTS `{$this->db_prefix}jxblog_category_lang` (
`id_jxblog_category` int(10) NOT NULL,
`id_lang` int(10) NOT NULL,
`name` varchar(40) NOT NULL default '',
`description` text NOT NULL,
`short_description` text NOT NULL,
`link_rewrite` varchar(40) NOT NULL default '',
`meta_keyword` text NOT NULL,
`meta_description` text NOT NULL,
`badge` varchar(100) NOT NULL default '',
PRIMARY KEY (`id_jxblog_category`, `id_lang`)
) ENGINE=$engine DEFAULT CHARSET=utf8",
"CREATE TABLE IF NOT EXISTS `{$this->db_prefix}jxblog_category_group` (
`id_jxblog_category` int(10) NOT NULL,
`id_group` int(10) NOT NULL,
PRIMARY KEY (`id_jxblog_category`, `id_group`)
) ENGINE=$engine DEFAULT CHARSET=utf8",
"CREATE TABLE IF NOT EXISTS `{$this->db_prefix}jxblog_category_shop` (
`id_jxblog_category` int(11) NOT NULL,
`id_shop` int(11) NOT NULL,
PRIMARY KEY (`id_jxblog_category`, `id_shop`)
) ENGINE=$engine DEFAULT CHARSET=utf8",
"CREATE TABLE IF NOT EXISTS `{$this->db_prefix}jxblog_post`(
`id_jxblog_post` int(10) NOT NULL auto_increment,
`id_jxblog_category_default` int(1) NOT NULL,
`author` int(1) NOT NULL,
`views` int(1) NOT NULL DEFAULT '0',
`active` int(1) NOT NULL,
`date_add` datetime NOT NULL,
`date_upd` datetime NOT NULL,
`date_start` datetime NOT NULL,
PRIMARY KEY (`id_jxblog_post`, `id_jxblog_category_default`)
) ENGINE=$engine DEFAULT CHARSET=utf8",
"CREATE TABLE IF NOT EXISTS `{$this->db_prefix}jxblog_post_lang`(
`id_jxblog_post` int(10) NOT NULL,
`id_lang` int(1) NOT NULL,
`name` varchar(100) NOT NULL default '',
`description` text NOT NULL,
`short_description` text NOT NULL,
`meta_keyword` text NOT NULL,
`meta_description` text NOT NULL,
`link_rewrite` varchar(100) NOT NULL default '',
PRIMARY KEY (`id_jxblog_post`, `id_lang`)
) ENGINE=$engine DEFAULT CHARSET=utf8",
"CREATE TABLE IF NOT EXISTS `{$this->db_prefix}jxblog_post_category`(
`id_jxblog_post` int(10) NOT NULL,
`id_jxblog_category` int(1) NOT NULL,
PRIMARY KEY (`id_jxblog_post`, `id_jxblog_category`)
) ENGINE=$engine DEFAULT CHARSET=utf8",
"CREATE TABLE IF NOT EXISTS `{$this->db_prefix}jxblog_tag` (
`id_jxblog_tag` int(10) NOT NULL auto_increment,
`id_lang` int(10) NOT NULL,
`tag` varchar(100) NOT NULL,
PRIMARY KEY (`id_jxblog_tag`, `id_lang`, `tag`)
) ENGINE=$engine DEFAULT CHARSET=utf8",
"CREATE TABLE IF NOT EXISTS `{$this->db_prefix}jxblog_tag_post` (
`id_jxblog_tag` int(10) NOT NULL,
`id_jxblog_post` int(10) NOT NULL,
PRIMARY KEY (`id_jxblog_tag`, `id_jxblog_post`)
) ENGINE=$engine DEFAULT CHARSET=utf8",
"CREATE TABLE IF NOT EXISTS `{$this->db_prefix}jxblog_image` (
`id_jxblog_image` int(10) NOT NULL auto_increment,
`name` varchar(40) NOT NULL default '',
`width` int(10) NOT NULL,
`height` int(10) NOT NULL,
`category` int(10) NOT NULL,
`category_thumb` int(10) NOT NULL,
`post` int(10) NOT NULL,
`post_thumb` int(10) NOT NULL,
`user` int(10) NOT NULL,
PRIMARY KEY (`id_jxblog_image`, `name`)
) ENGINE=$engine DEFAULT CHARSET=utf8"
);
foreach ($queries as $query) {
$success &= $this->db->execute($query);
}
return $success;
}
public function dropTables()
{
$sql = "DROP TABLE IF EXISTS
`{$this->db_prefix}jxblog_category`,
`{$this->db_prefix}jxblog_category_lang`,
`{$this->db_prefix}jxblog_category_group`,
`{$this->db_prefix}jxblog_category_shop`,
`{$this->db_prefix}jxblog_post`,
`{$this->db_prefix}jxblog_post_lang`,
`{$this->db_prefix}jxblog_post_category`,
`{$this->db_prefix}jxblog_tag`,
`{$this->db_prefix}jxblog_tag_post`,
`{$this->db_prefix}jxblog_image`";
return $this->db->execute($sql);
}
}

View File

@@ -0,0 +1,112 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class JXBlogTabManager
{
private $module;
private $mainTab;
private $settingsTab;
private $tabs;
private $settingsSubTabs;
public function __construct($module, $tabs, $settingsSubTabs)
{
$this->module = $module;
$this->mainTab = array(
'class_name' => 'AdminJXBlog',
'module' => $this->module->name,
'name' => 'JX Blog'
);
$this->settingsTab = array(
'class_name' => 'AdminJXBlogSettings',
'module' => $this->module->name,
'name' => 'Settings'
);
$this->tabs = $tabs;
$this->settingsSubTabs = $settingsSubTabs;
}
/**
* Add related to module tabs to the main navigation menu
*
* @return bool
*/
public function addTabs()
{
$tabId = TabCore::getIdFromClassName($this->mainTab['class_name']);
foreach ($this->tabs as $item) {
$this->addTab($item, $tabId);
}
$idSettingsTab = TabCore::getIdFromClassName($this->settingsTab['class_name']);
if (!$idSettingsTab) {
$idSettingsTab = $this->addTab($this->settingsTab, $tabId);
}
if (count($this->settingsSubTabs)) {
foreach ($this->settingsSubTabs as $newSubTab) {
$this->addTab($newSubTab, $idSettingsTab);
}
}
return true;
}
protected function addTab($tab, $parent)
{
$t = new Tab();
$t->class_name = $tab['class_name'];
$t->id_parent = $parent;
$t->module = $tab['module'];
foreach ($this->module->languages as $lang) {
$t->name[$lang['id_lang']] = $this->module->l($tab['name']);
}
if (!$t->save()) {
return false;
}
return $t->id;
}
/**
* Remove related to module tabs to the main navigation menu
*
* @return bool
*/
public function removeTabs()
{
foreach (array_merge($this->tabs, $this->settingsSubTabs) as $t) {
if ($t) {
$t = new Tab(TabCore::getIdFromClassName($t['class_name']));
if (!$t->delete()) {
return false;
}
}
}
return true;
}
}

View File

@@ -0,0 +1,201 @@
<?php
/**
* 2017-2019 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2019 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class TabManager
{
private $module;
/**
* @var array main JX Modules tab
*/
private $jxMainTab = array(
'name' => 'JX Modules',
'class_name' => 'AdminJxModules'
);
/**
* @var array the main module tab
*/
private $moduleMainTab = array(
'name' => 'JX Blog',
'class_name' => 'AdminJXBlog',
'icon' => 'notes',
'parent_class_name' => 'AdminJxModules'
);
/**
* @var array related module's tabs
*/
private $moduleTabs = array(
array(
'name' => 'Categories',
'class_name' => 'AdminJXBlogCategories',
'parent_class_name' => 'AdminJXBlog'
),
array(
'name' => 'Posts',
'class_name' => 'AdminJXBlogPosts',
'parent_class_name' => 'AdminJXBlog'
),
array(
'name' => 'Images Manager',
'class_name' => 'AdminJXBlogImages',
'parent_class_name' => 'AdminJXBlog'
),
array(
'name' => 'Settings',
'class_name' => 'AdminJXBlogSettings',
'parent_class_name' => 'AdminJXBlog'
),
array(
'name' => 'Main settings',
'class_name' => 'AdminJXBlogMainSettings',
'parent_class_name' => 'AdminJXBlogSettings'
)
);
/**
* TabManager constructor.
*
* @param $module the module's name
*/
public function __construct()
{
$this->module = 'jxblog';
}
/**
* Install common JX modules tab if it doesn't already exist and install all module's tabs
*
* @return bool
*/
public function installTabs()
{
if ($mainTabId = $this->installMainTab($this->jxMainTab, false)) {
if ($this->installModuleTab($this->moduleMainTab, $mainTabId)) {
if ($this->installChildrenTabs()) {
return true;
}
}
return true;
}
return false;
}
/**
* Install top JX Modules tab. Check if it already exists and install it if not
*
* @param $tab determination of tab
* @param bool $module is the tab related to certain module or it is common
*
* @return bool|int main tab id if everything ok or error if errors occurred
*/
public function installMainTab($tab, $module = true)
{
if ($tabId = \Tab::getIdFromClassName($tab['class_name'])) {
return $tabId;
} else {
return $this->installTab($tab, $module);
}
}
/**
* Install the module main tab related to the top tab
* @param $tab determination of tab
* @param $id_parent id of the top tab
*
* @return bool|int
*/
public function installModuleTab($tab, $id_parent)
{
$tab = array_merge($tab, array('id_parent' => $id_parent));
return $this->installTab($tab);
}
/**
* Install all related module's tabs.
* @param $id_parent id of the module top tab
*
* @return bool|int
*/
public function installChildrenTabs()
{
$result = true;
foreach ($this->moduleTabs as $tab) {
$id_parent = Tab::getIdFromClassName($tab['parent_class_name']);
$result &= $this->installModuleTab($tab, $id_parent);
}
return $result;
}
/**
* Install tab
*
* @param $tab
* @param bool $module
*
* @return bool|int
*/
private function installTab($tab, $module = true)
{
$t = new \Tab();
if ($module) {
$t->module = $this->module;
}
$t->class_name = $tab['class_name'];
if (isset($tab['icon'])) {
$t->icon = $tab['icon'];
}
if (isset($tab['id_parent'])) {
$t->id_parent = $tab['id_parent'];
}
foreach (\Language::getLanguages(false) as $language) {
$t->name[$language['id_lang']] = $tab['name'];
}
if (!$t->save()) {
return false;
}
return $t->id;
}
/**
* Remove tab if it doesn't contain any tabs related to other modules
*
* @return bool
*/
public function removeTab()
{
$id_tab = \Tab::getIdFromClassName('AdminJxModules');
if ($id_tab && \Tab::getNbTabs($id_tab) !== 1) {
return true;
} else {
$tab = new \Tab($id_tab);
if (!$tab->delete()) {
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,32 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,9 @@
drwxr-xr-x 2 30094 users 9 Oct 6 10:16 .
drwxr-xr-x 9 30094 users 16 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 0 Aug 31 2021 de.php
-rw-r--r-- 1 30094 users 330 Aug 31 2021 en.php
-rw-r--r-- 1 30094 users 0 Aug 31 2021 es.php
-rw-r--r-- 1 30094 users 0 Aug 31 2021 fr.php
-rw-r--r-- 1 30094 users 891 Aug 31 2021 index.php
-rw-r--r-- 1 30094 users 661 Sep 2 2021 pl.php
-rw-r--r-- 1 30094 users 0 Aug 31 2021 ru.php

View File

View File

@@ -0,0 +1,6 @@
<?php
global $_MODULE;
$_MODULE = array();
$_MODULE['<{jxblog}prestashop>jxblog_e0c824c492bd0e3f2508f794dfd54e8d'] = 'The best module for Prestashop platform.';
$_MODULE['<{jxblog}prestashop>jxblog_270ea75d9da9ab2ba25886ccf538e86e'] = 'Are you sure that you want to delete the module? All related data will be deleted forever!';

View File

View File

View File

@@ -0,0 +1,32 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,11 @@
<?php
global $_MODULE;
$_MODULE = array();
$_MODULE['<{jxblog}prestashop>jxblog_3cfd94e5b1e020a2b88c15f49d57886e'] = 'Kategorie';
$_MODULE['<{jxblog}prestashop>jxblog_8cf04a9734132302f96da8e113e80ce5'] = 'Strona główna';
$_MODULE['<{jxblog}prestashop>jxblog_dd1f775e443ff3b9a89270713580a51b'] = 'Poprzedni';
$_MODULE['<{jxblog}prestashop>jxblog_10ac3d04253ef7e1ddc73e6091c0cd55'] = 'Następny';
$_MODULE['<{jxblog}prestashop>categories_3cfd94e5b1e020a2b88c15f49d57886e'] = 'Kategorie';
$_MODULE['<{jxblog}prestashop>blog_3cfd94e5b1e020a2b88c15f49d57886e'] = 'Kategorie';
$_MODULE['<{jxblog}prestashop>search_9c901efc7503d96e7ad8feb82ff75b82'] = 'Kategorie';

View File

View File

@@ -0,0 +1,7 @@
drwxr-xr-x 6 30094 users 7 Oct 6 10:16 .
drwxr-xr-x 9 30094 users 16 Oct 6 10:16 ..
drwxr-xr-x 2 30094 users 4 Oct 6 10:16 css
-rw-r--r-- 1 30094 users 891 Aug 31 2021 index.php
drwxr-xr-x 2 30094 users 5 Oct 6 10:16 js
drwxr-xr-x 2 30094 users 6 Oct 6 10:16 scss
drwxr-xr-x 5 30094 users 6 Oct 6 10:16 templates

View File

@@ -0,0 +1,4 @@
drwxr-xr-x 2 30094 users 4 Oct 6 10:16 .
drwxr-xr-x 6 30094 users 7 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 1736 Aug 31 2021 jxblog.css
-rw-r--r-- 1 30094 users 685 Aug 31 2021 jxblog_admin.css

View File

@@ -0,0 +1,69 @@
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
.blog-category .blog-category-info {
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
-moz-box-orient: vertical;
-moz-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-align: start;
-webkit-align-items: flex-start;
-moz-box-align: start;
-ms-flex-align: start;
align-items: flex-start;
}
.blog-category .blog-category-info .btn {
-webkit-box-ordinal-group: 2;
-webkit-order: 1;
-moz-box-ordinal-group: 2;
-ms-flex-order: 1;
order: 1;
}
.blog-category .blog-category-info .btn:not(.active) span:last-child {
display: none;
}
.blog-category .blog-category-info .btn:not(.active) + .blog-category-description-short + .blog-category-description {
display: none;
}
.blog-category .blog-category-info .btn.active span:first-child {
display: none;
}
.blog-category .blog-category-info .btn.active + .blog-category-description-short {
display: none;
}
.post-meta.author-hidden .post-author {
display: none;
}

View File

@@ -0,0 +1,25 @@
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
a#collapse-all-blog-categories-tree, a#expand-all-blog-categories-tree {
display: none;
}

View File

@@ -0,0 +1,32 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,5 @@
drwxr-xr-x 2 30094 users 5 Oct 6 10:16 .
drwxr-xr-x 6 30094 users 7 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 891 Aug 31 2021 index.php
-rw-r--r-- 1 30094 users 593 Aug 31 2021 jxblog.js
-rw-r--r-- 1 30094 users 593 Aug 31 2021 jxblog_admin.js

View File

@@ -0,0 +1,32 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,21 @@
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/

View File

@@ -0,0 +1,21 @@
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/

View File

@@ -0,0 +1,6 @@
drwxr-xr-x 2 30094 users 6 Oct 6 10:16 .
drwxr-xr-x 6 30094 users 7 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 891 Aug 31 2021 index.php
-rw----r-- 1 30094 users 1271 Sep 5 07:45 jxblog.css
-rw----r-- 1 30094 users 289 Sep 5 07:45 jxblog.css.map
-rw-r--r-- 1 30094 users 1203 Aug 31 2021 jxblog.scss

View File

@@ -0,0 +1,32 @@
<?php
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,2 @@
.blog-category .blog-category-info{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.blog-category .blog-category-info .btn{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.blog-category .blog-category-info .btn:not(.active) span:last-child{display:none}.blog-category .blog-category-info .btn:not(.active)+.blog-category-description-short+.blog-category-description{display:none}.blog-category .blog-category-info .btn.active span:first-child{display:none}.blog-category .blog-category-info .btn.active+.blog-category-description-short{display:none}.post-meta.author-hidden .post-author{display:none}
/*# sourceMappingURL=jxblog.css.map */

View File

@@ -0,0 +1,9 @@
{
"version": 3,
"mappings": "AAsBA,AACE,cADY,CACZ,mBAAmB,AAAC,CAClB,OAAO,CAAE,IAAI,CACb,cAAc,CAAE,MAAM,CACtB,WAAW,CAAE,UAAU,CAoBxB,AAxBH,AAKI,cALU,CACZ,mBAAmB,CAIjB,IAAI,AAAC,CACH,KAAK,CAAE,CAAC,CAiBT,AAvBL,AAQQ,cARM,CACZ,mBAAmB,CAIjB,IAAI,AAED,IAAK,CAAA,OAAO,EACX,IAAI,AAAA,WAAW,AAAC,CACd,OAAO,CAAE,IAAI,CACd,AAVT,AAWQ,cAXM,CACZ,mBAAmB,CAIjB,IAAI,AAED,IAAK,CAAA,OAAO,EAIT,gCAAgC,CAAG,0BAA0B,AAAC,CAC9D,OAAO,CAAE,IAAI,CACd,AAbT,AAgBQ,cAhBM,CACZ,mBAAmB,CAIjB,IAAI,AAUD,OAAO,CACN,IAAI,AAAA,YAAY,AAAC,CACf,OAAO,CAAE,IAAI,CACd,AAlBT,AAmBQ,cAnBM,CACZ,mBAAmB,CAIjB,IAAI,AAUD,OAAO,CAIJ,gCAAgC,AAAC,CACjC,OAAO,CAAE,IAAI,CACd,AAMT,AAEI,UAFM,AACP,cAAc,CACb,YAAY,AAAC,CACX,OAAO,CAAE,IAAI,CACd",
"sources": [
"jxblog.scss"
],
"names": [],
"file": "jxblog.css"
}

View File

@@ -0,0 +1,56 @@
/**
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
.blog-category {
.blog-category-info {
display: flex;
flex-direction: column;
align-items: flex-start;
.btn {
order: 1;
&:not(.active) {
span:last-child {
display: none;
}
+ .blog-category-description-short + .blog-category-description {
display: none;
}
}
&.active {
span:first-child {
display: none;
}
+ .blog-category-description-short {
display: none;
}
}
}
}
}
.post-meta {
&.author-hidden {
.post-author {
display: none;
}
}
}

View File

@@ -0,0 +1,6 @@
drwxr-xr-x 5 30094 users 6 Oct 6 10:16 .
drwxr-xr-x 6 30094 users 7 Oct 6 10:16 ..
drwxr-xr-x 5 30094 users 5 Oct 6 10:16 admin
drwxr-xr-x 3 30094 users 10 Oct 6 10:16 front
drwxr-xr-x 2 30094 users 3 Oct 6 10:16 hook
-rw-r--r-- 1 30094 users 891 Aug 31 2021 index.php

View File

@@ -0,0 +1,5 @@
drwxr-xr-x 5 30094 users 5 Oct 6 10:16 .
drwxr-xr-x 5 30094 users 6 Oct 6 10:16 ..
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 jx_blog_categories
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 jx_blog_images
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 jx_blog_posts

View File

@@ -0,0 +1,3 @@
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 .
drwxr-xr-x 5 30094 users 5 Oct 6 10:16 ..
drwxr-xr-x 4 30094 users 4 Oct 6 10:16 helpers

View File

@@ -0,0 +1,4 @@
drwxr-xr-x 4 30094 users 4 Oct 6 10:16 .
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 ..
drwxr-xr-x 2 30094 users 3 Oct 6 10:16 form
drwxr-xr-x 2 30094 users 3 Oct 6 10:16 list

View File

@@ -0,0 +1,3 @@
drwxr-xr-x 2 30094 users 3 Oct 6 10:16 .
drwxr-xr-x 4 30094 users 4 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 1034 Aug 31 2021 form.tpl

View File

@@ -0,0 +1,42 @@
{*
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*}
{extends file="helpers/form/form.tpl"}
{block name="script"}
var ps_force_friendly_product = false;
{/block}
{block name="input"}
{if $input.name == "link_rewrite"}
<script type="text/javascript">
{if isset($PS_ALLOW_ACCENTED_CHARS_URL) && $PS_ALLOW_ACCENTED_CHARS_URL}
var PS_ALLOW_ACCENTED_CHARS_URL = 1;
{else}
var PS_ALLOW_ACCENTED_CHARS_URL = 0;
{/if}
</script>
{$smarty.block.parent}
{else}
{$smarty.block.parent}
{/if}
{/block}

View File

@@ -0,0 +1,3 @@
drwxr-xr-x 2 30094 users 3 Oct 6 10:16 .
drwxr-xr-x 4 30094 users 4 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 1567 Aug 31 2021 list_header.tpl

View File

@@ -0,0 +1,48 @@
{*
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*}
{extends file="helpers/list/list_header.tpl"}
{block name=override_header}
<ul class="breadcrumb cat_bar2">
{assign var=i value=0}
{foreach $categories_tree key=key item=category}
<li>
{if $i++ == 0}
<i class="icon-home"></i>
{assign var=params_url value=""}
{elseif isset($category.id_jxblog_category)}
{assign var=params_url value="&id_jxblog_category={$category.id_jxblog_category|intval}&viewcategory"}
{/if}
{if isset($category.id_jxblog_category) && $category.id_jxblog_category == $categories_tree_current_id}
{$category.name|escape:'html':'UTF-8'}
<a class="edit" href="{$category.edit_link}" title="{l s='Edit' d='Admin.Global'}">
&nbsp;<i class="icon-pencil"></i> {l s='Edit' d='Admin.Global'}
</a>
{else}
<a href="{$current|escape:'html':'UTF-8'}{$params_url|escape:'html':'UTF-8'}&amp;token={$token|escape:'html':'UTF-8'}">{$category.name|escape:'html':'UTF-8'}</a>
{/if}
</li>
{/foreach}
</ul>
{/block}

View File

@@ -0,0 +1,3 @@
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 .
drwxr-xr-x 5 30094 users 5 Oct 6 10:16 ..
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 helpers

View File

@@ -0,0 +1,3 @@
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 .
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 ..
drwxr-xr-x 2 30094 users 3 Oct 6 10:16 form

View File

@@ -0,0 +1,3 @@
drwxr-xr-x 2 30094 users 3 Oct 6 10:16 .
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 4093 Aug 31 2021 form.tpl

View File

@@ -0,0 +1,84 @@
{*
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*}
{extends file="helpers/form/form.tpl"}
{block name="field"}
{if $input.type == 'multilingual_image'}
<div class="row">
{foreach from=$languages item=language}
{if $languages|count > 1}
<div class="translatable-field lang-{$language.id_lang|escape:'htmlall':'UTF-8'}" {if $language.id_lang != $defaultFormLanguage}style="display:none"{/if}>
{/if}
<div class="col-lg-6">
{if isset($input.images[$language.id_lang]) && $input.images[$language.id_lang]}
<img
src="{$input.images[$language.id_lang]|escape:'html':'UTF-8'}"
class="img-thumbnail" />
<input class="hidden-image-name" type="hidden" name="old_image_{$input.images[$language.id_lang]|escape:'htmlall':'UTF-8'}" value="{$input.images[$language.id_lang]|escape:'html':'UTF-8'}" />
{/if}
<div class="dummyfile input-group">
<input id="{$input.name|escape:'htmlall':'UTF-8'}_{$language.id_lang|escape:'htmlall':'UTF-8'}" type="file" name="{$input.name|escape:'htmlall':'UTF-8'}_{$language.id_lang|escape:'htmlall':'UTF-8'}" class="hide-file-upload"/>
<span class="input-group-addon"><i class="icon-file"></i></span>
<input id="{$input.name|escape:'htmlall':'UTF-8'}_{$language.id_lang|escape:'htmlall':'UTF-8'}-name" type="text" class="disabled" name="{$input.name|escape:'htmlall':'UTF-8'}_{$language.id_lang|escape:'htmlall':'UTF-8'}" readonly/>
<span class="input-group-btn">
<button id="{$input.name|escape:'htmlall':'UTF-8'}_{$language.id_lang|escape:'htmlall':'UTF-8'}-selectbutton" type="button" name="submitAddAttachments" class="btn btn-default">
<i class="icon-folder-open"></i> {l s='Choose a file' mod='jxblog'}
</button>
</span>
</div>
<p class="help-block">{if isset($input.description) && $input.description}{$input.description|escape:'htmlall':'UTF-8'}{/if}</p>
</div>
{if $languages|count > 1}
<div class="col-lg-2">
<button type="button" class="btn btn-default dropdown-toggle" tabindex="-1" data-toggle="dropdown">
{$language.iso_code|escape:'htmlall':'UTF-8'}
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
{foreach from=$languages item=lang}
<li>
<a href="javascript:hideOtherLanguage({$lang.id_lang|escape:'htmlall':'UTF-8'});" tabindex="-1">{$lang.name|escape:'htmlall':'UTF-8'}</a>
</li>
{/foreach}
</ul>
</div>
{/if}
{if $languages|count > 1}
</div>
{/if}
<script>
$(document).ready(function() {
$('#{$input.name|escape:"htmlall":"UTF-8"}_{$language.id_lang|escape:"htmlall":"UTF-8"}-selectbutton').click(function(e) {
$('#{$input.name|escape:"htmlall":"UTF-8"}_{$language.id_lang|escape:"htmlall":"UTF-8"}').trigger('click');
});
$('#{$input.name|escape:"htmlall":"UTF-8"}_{$language.id_lang|escape:"htmlall":"UTF-8"}').change(function(e) {
var val = $(this).val();
var file = val.split(/[\\/]/);
$('#{$input.name|escape:"htmlall":"UTF-8"}_{$language.id_lang|escape:"htmlall":"UTF-8"}-name').val(file[file.length - 1]);
});
});
</script>
{/foreach}
</div>
{/if}
{$smarty.block.parent}
{/block}

View File

@@ -0,0 +1,3 @@
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 .
drwxr-xr-x 5 30094 users 5 Oct 6 10:16 ..
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 helpers

View File

@@ -0,0 +1,3 @@
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 .
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 ..
drwxr-xr-x 2 30094 users 3 Oct 6 10:16 form

View File

@@ -0,0 +1,3 @@
drwxr-xr-x 2 30094 users 3 Oct 6 10:16 .
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 3212 Aug 31 2021 form.tpl

View File

@@ -0,0 +1,82 @@
{*
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*}
{extends file="helpers/form/form.tpl"}
{block name="script"}
var ps_force_friendly_product = false;
{/block}
{block name="input"}
{if $input.name == "link_rewrite"}
<script type="text/javascript">
{if isset($PS_ALLOW_ACCENTED_CHARS_URL) && $PS_ALLOW_ACCENTED_CHARS_URL}
var PS_ALLOW_ACCENTED_CHARS_URL = 1;
{else}
var PS_ALLOW_ACCENTED_CHARS_URL = 0;
{/if}
</script>
{$smarty.block.parent}
{elseif $input.type == "cat_list"}
<div id="category_block">
<div class="panel">
<ul id="associated-categories-tree" class="cattree tree">
{foreach from=$input.categories item='category' name='categories_loop'}
<li class="tree-folder">
<span class="tree-folder-name">
<input type="radio" {if $input.id_jxblog_category_default && $input.id_jxblog_category_default == $category.id_jxblog_category}checked="checked"{elseif $smarty.foreach.categories_loop.iteration == 1}checked="checked"{/if} name="id_jxblog_category_default" value="{$category.id_jxblog_category}" />
<input id="jxcategoryBox{$category.id_jxblog_category}" {if $input.related_categories && $category.id_jxblog_category|in_array:$input.related_categories}checked="checked"{/if} type="checkbox" name="jxcategoryBox[]" value="{$category.id_jxblog_category}" />
<label class="tree-toggler"> {$category.name}</label>
</span>
</li>
{/foreach}
</div>
</div>
{elseif $input.type == "autocomplete"}
{if isset($input.url) && $input.url}
<input type="hidden" name="ajax_url" value="{$input.url}" />
{/if}
{assign var="type" value="related_`$input.id`"}
<input id="input{$input.id}" name="input{$input.id}" value="{if $fields_value[$type]}{foreach from=$fields_value[$type] item='item'}{$item.id}-{/foreach}{else}-{/if}" type="hidden">
<input id="name{$input.id}" name="name{$input.id}" value="{if $fields_value[$type]}{foreach from=$fields_value[$type] item='item'}{$item.name}¤{/foreach}{else}¤{/if}" type="hidden">
<div id="ajax_choose_{$input.id}">
<div class="input-group">
<input type="text" id="{$input.id}_autocomplete_input" name="{$input.id}_autocomplete_input"/>
<span class="input-group-addon"><i class="icon-search"></i></span>
</div>
</div>
<div id="div{$input.id}">
{if $fields_value[$type]}
{foreach from=$fields_value[$type] item='item'}
<div class="form-control-static">
<button type="button" class="btn btn-default del{$input.id}" name="{$item.id}">
<i class="icon-remove text-danger"></i>
</button>
{$item.name}
</div>
{/foreach}
{/if}
</div>
{else}
{$smarty.block.parent}
{/if}
{/block}

View File

@@ -0,0 +1,10 @@
drwxr-xr-x 3 30094 users 10 Oct 6 10:16 .
drwxr-xr-x 5 30094 users 6 Oct 6 10:16 ..
drwxr-xr-x 2 30094 users 4 Oct 6 10:16 _partials
-rw-r--r-- 1 30094 users 1017 Aug 31 2021 author.tpl
-rw-r--r-- 1 30094 users 2860 Aug 31 2021 blog.tpl
-rw-r--r-- 1 30094 users 2420 Aug 31 2021 categories.tpl
-rw-r--r-- 1 30094 users 3575 Aug 31 2021 category.tpl
-rw-r--r-- 1 30094 users 2517 Aug 31 2021 post.tpl
-rw-r--r-- 1 30094 users 1181 Aug 31 2021 search.tpl
-rw-r--r-- 1 30094 users 988 Aug 31 2021 tag.tpl

View File

@@ -0,0 +1,4 @@
drwxr-xr-x 2 30094 users 4 Oct 6 10:16 .
drwxr-xr-x 3 30094 users 10 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 1255 Aug 31 2021 pagination.tpl
-rw-r--r-- 1 30094 users 1998 Aug 31 2021 post-miniature.tpl

View File

@@ -0,0 +1,40 @@
{*
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*}
<nav class="pagination">
<div class="col-md-4">
{l s='Showing %from%-%to% of %total% item(s)' d='Shop.Theme.Catalog' sprintf=['%from%' => $pagination.from ,'%to%' => $pagination.to, '%total%' => $pagination.total]}
</div>
<div class="col-md-6 offset-md-2 pr-0">
{if isset($pagination.steps) && $pagination.steps}
<ul class="page-list clearfix text-sm-center">
{foreach from=$pagination.steps item='step'}
<li {if $step.active}class="current"{/if}>
{if !$step.active}
<a href="{$step.url}">{/if}{$step.name}{if !$step.active}</a>
{/if}
</li>
{/foreach}
</ul>
{/if}
</div>
</nav>

View File

@@ -0,0 +1,52 @@
{*
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*}
<section class="blog-posts row">
{foreach from=$posts item='post'}
{block name='blog_post_miniature'}
<article class="bp-miniature col-sm-6 col-lg-4 mb-3">
<div class="bp-miniature-container card">
<div class="bp-thumbnail">
<a href="{url entity='module' name='jxblog' controller='post' params = ['id_jxblog_post' => $post.id_jxblog_post, 'rewrite' => $post.link_rewrite]}">
<img class="img-fluid" src="{JXBlogImageManager::getImage('post_thumb', $post.id_jxblog_post, 'post_listing')}" alt="{$post.name}">
</a>
</div>
<div class="card-body p-1">
<h1 class="h4 bp-name">
<a href="{url entity='module' name='jxblog' controller='post' params = ['id_jxblog_post' => $post.id_jxblog_post, 'rewrite' => $post.link_rewrite]}">
{$post.name}
</a>
</h1>
{if $post.short_description}
<div class="bp-short-description">
{$post.short_description nofilter}
</div>
{/if}
<a class="btn btn-primary" href="{url entity='module' name='jxblog' controller='post' params = ['id_jxblog_post' => $post.id_jxblog_post, 'rewrite' => $post.link_rewrite]}">
{l s='Read more' d='Shop.Theme.Actions'}
</a>
</div>
</div>
</article>
{/block}
{/foreach}
</section>

View File

@@ -0,0 +1,37 @@
{*
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*}
{extends file=$layout}
{block name='content'}
<section id="main">
<h1>{$author->firstname} {$author->lastname}</h1>
{if $posts}
{include file="module:jxblog/views/templates/front/_partials/post-miniature.tpl"}
{if $pagination}
{include file="module:jxblog/views/templates/front/_partials/pagination.tpl"}
{/if}
{else}
<p>{l s='There are no posts' mod='jxblog'}</p>
{/if}
</section>
{/block}

View File

@@ -0,0 +1,76 @@
{*
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*}
{extends file=$layout}
{block name='content'}
<section id="main">
{block name='blog_categories_header'}
<h1><a href="{url entity='module' name='jxblog' controller='categories'}" title="{l s='All categories' mod='jxblog'}">{l s='Blog categories' mod='jxblog'}</a></h1>
{/block}
{if $categories}
<section class="blog-categories row">
{foreach from=$categories item='category'}
{block name='blog_category_miniature'}
<article class="bc-miniature col-sm-6 col-lg-4">
<div class="bc-miniature-container card">
<div class="bc-thumbnail">
<a href="{url entity='module' name='jxblog' controller='category' params = ['id_jxblog_category' => $category.id_jxblog_category, 'rewrite' => $category.link_rewrite]}">
<img class="img-fluid" src="{JXBlogImageManager::getImage('category_thumb', $category.id_jxblog_category, 'category_listing')}" alt="{$category.name}">
</a>
</div>
<div class="card-body p-1">
<h1 class="h4 bc-name">
<a href="{url entity='module' name='jxblog' controller='category' params = ['id_jxblog_category' => $category.id_jxblog_category, 'rewrite' => $category.link_rewrite]}">
{$category.name}
</a>
</h1>
{if $category.short_description}
<div class="bc-short-description">
{$category.short_description nofilter}
</div>
{/if}
</div>
</div>
</article>
{/block}
{/foreach}
</section>
{if Configuration::get('JXBLOG_DISPLAY_PRODUCTS_ON_BLOG_PAGE') && $posts}
<hr class="my-3">
{block name='blog_posts_header'}
<h1>{l s='Blog posts' mod='jxblog'}</h1>
{/block}
{include file="module:jxblog/views/templates/front/_partials/post-miniature.tpl"}
{if $pagination}
{include file="module:jxblog/views/templates/front/_partials/pagination.tpl"}
{/if}
{/if}
{else}
{l s='There are no categories in the blog yet' mod='jxblog'}
{/if}
</section>
{/block}

View File

@@ -0,0 +1,70 @@
{*
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*}
{extends file=$layout}
{block name='content'}
<section id="main">
{block name='blog_categories_header'}
<h1>{l s='Blog categories' mod='jxblog'}</h1>
{/block}
{if $categories}
<section class="blog-categories row">
{foreach from=$categories item='category'}
{block name='blog_category_miniature'}
<article class="bc-miniature col-sm-6 col-lg-4">
<div class="bc-miniature-container card">
<div class="bc-thumbnail">
<a href="{url entity='module' name='jxblog' controller='category' params = ['id_jxblog_category' => $category.id_jxblog_category, 'rewrite' => $category.link_rewrite]}">
<img class="img-fluid" src="{JXBlogImageManager::getImage('category_thumb', $category.id_jxblog_category, 'category_listing')}" alt="{$category.name}">
</a>
</div>
<div class="card-body p-1">
<h1 class="h4 bc-name">
<a href="{url entity='module' name='jxblog' controller='category' params = ['id_jxblog_category' => $category.id_jxblog_category, 'rewrite' => $category.link_rewrite]}">
{$category.name}
</a>
</h1>
{if $category.short_description}
<div class="bc-short-description">
{$category.short_description nofilter}
</div>
{/if}
</div>
</div>
</article>
{/block}
{/foreach}
</section>
{if $pagination}
{include file="module:jxblog/views/templates/front/_partials/pagination.tpl"}
{/if}
{else}
{l s='There are no categories in the blog yet' mod='jxblog'}
{/if}
</section>
{/block}

View File

@@ -0,0 +1,87 @@
{*
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*}
{extends file=$layout}
{block name='head_seo_description'}{$page.meta.description}{/block}
{block name='head_seo_keywords'}{$page.meta.keywords}{/block}
{block name='content'}
<section id="main">
<div id="blog-category-{$category.id_jxblog_category}" class="blog-category">
<div class="blog-category-image mb-2">
<img class="img-fluid" src="{JXBlogImageManager::getImage('category', $category.id_jxblog_category, 'category_info')}" alt="{$category.name}">
</div>
<div class="blog-category-info">
<h1>{$category.name} <span class="badge badge-primary">{$category.badge}</span></h1>
{if $category.short_description && $category.description}
<button type="button" class="btn btn-secondary btn-sm" data-toggle="button" aria-pressed="false" autocomplete="off">
<span>{l s='Read more' d='Shop.Theme.Actions'}</span>
<span>{l s='Hide' d='Shop.Theme.Actions'}</span>
</button>
<div class="blog-category-description-short text-muted">
{$category.short_description nofilter}
</div>
<div class="blog-category-description text-muted">
{$category.description nofilter}
</div>
{elseif $category.short_description}
<div class="blog-category-description-short text-muted">
{$category.short_description nofilter}
</div>
{elseif $category.description}
<div class="blog-category-description text-muted">
{$category.description nofilter}
</div>
{/if}
</div>
</div>
{if isset($sub_categories) && $sub_categories}
<div class="sub-categories">
<h3>{l s='Sub-categories' mod='jxblog'}</h3>
<div class="row">
{foreach from=$sub_categories item=sub_category name=sub_category}
<div class="bsc-miniature col-sm-2">
<a href="{url entity='module' name='jxblog' controller='category' params = ['id_jxblog_category' => $sub_category.id_jxblog_category, 'rewrite' => $sub_category.link_rewrite]}">
<img class="img-fluid" src="{JXBlogImageManager::getImage('category', $sub_category.id_jxblog_category, 'category_info')}" alt="{$sub_category.name}">
</a>
<h5>
<a href="{url entity='module' name='jxblog' controller='category' params = ['id_jxblog_category' => $sub_category.id_jxblog_category, 'rewrite' => $sub_category.link_rewrite]}">
{$sub_category.name}
</a>
</h5>
</div>
{/foreach}
</div>
</div>
{/if}
{if $posts}
<hr class="my-3">
{include file="module:jxblog/views/templates/front/_partials/post-miniature.tpl"}
{if $pagination}
{include file="module:jxblog/views/templates/front/_partials/pagination.tpl"}
{/if}
{else}
<p>{l s='There are no posts in the category' mod='jxblog'}</p>
{/if}
</section>
{/block}

View File

@@ -0,0 +1,82 @@
{*
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*}
{extends file=$layout}
{block name='head_seo_description'}{$post.meta_description}{/block}
{block name='head_seo_keywords'}{$post.meta_keyword}{/block}
{block name='content'}
<section id="main">
{if $post}
{block name='blog_post_header'}
<h1>{$post.name}</h1>
{/block}
<p class="post-meta{if !$displayAuthor} author-hidden{/if}">
{l s='Posted on %date% at %time% [0]by [1"]%link%["1]%name%[/1][/0]'
sprintf=[
'%date%' => {$post.date_start|date_format},
'%time%' => {$post.date_start|date_format:"%H:%M"},
'%link%' => {url entity='module' name='jxblog' controller='author' params = ['author' => $post.id_author]},
'%name%' => {$post.author},
'[0]' => '<span class="post-author">',
'[/0]' => '</span>',
'[1"]' => '<a href="',
'["1]' => '">',
'[/1]' => '</a>'
]
d='Shop.Theme.Global'
}{if $displayViews && $post.views} - <small class="post-views">{l s='Views' mod='jxblog'} ({$post.views})</small>{/if}
</p>
<div class="post-image mb-2">
<img class="img-fluid" src="{JXBlogImageManager::getImage('post', $post.id_jxblog_post, 'post_default')}" alt="{$post.name}"/>
</div>
{if $post.description}
<div class="post-description">
{$post.description nofilter}
</div>
{/if}
{if $tags}
<hr>
<div class="post-tags">
{l s='Tagged' mod='jxblog'}
{foreach from=$tags item='tag' name="tag"}
<a href="{$link->getModuleLink('jxblog', 'tag', ['id_jxblog_tag' => $tag.id_jxblog_tag])}">{$tag.tag}</a>{if !$smarty.foreach.tag.last},{/if}
{/foreach}
</div>
{/if}
<hr>
{hook h="displayJXBlogPostFooter" post=$post}
{else}
<p>{l s='Post doesn\'t exist or you don\'t have permissions to access it.' mod='jxblog'}</p>
{/if}
</section>
{/block}

View File

@@ -0,0 +1,37 @@
{*
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*}
{extends file=$layout}
{block name='content'}
<section id="main">
<h1>{l s='Search by:' mod='jxblog'}{$blog_search_query}{l s=' in:' mod='jxblog'}{if isset($active_blog_category) && $active_blog_category}{$active_blog_category}{else}{l s=' All categories' mod='jxblog'}{/if}</h1>
{if $posts}
{include file="module:jxblog/views/templates/front/_partials/post-miniature.tpl"}
{if $pagination}
{include file="module:jxblog/views/templates/front/_partials/pagination.tpl"}
{/if}
{else}
<p>{l s='There are no posts' mod='jxblog'}</p>
{/if}
</section>
{/block}

View File

@@ -0,0 +1,37 @@
{*
* 2017-2018 Zemez
*
* JX Blog
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul)
* @copyright 2017-2018 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*}
{extends file=$layout}
{block name='content'}
<section id="main">
<h1>{$tag->tag}</h1>
{if $posts}
{include file="module:jxblog/views/templates/front/_partials/post-miniature.tpl"}
{if $pagination}
{include file="module:jxblog/views/templates/front/_partials/pagination.tpl"}
{/if}
{else}
<p>{l s='There are no posts' mod='jxblog'}</p>
{/if}
</section>
{/block}

Some files were not shown because too many files have changed in this diff Show More