From 30a7fdd198c5802e8e979c6c26a15a77abf4cd13 Mon Sep 17 00:00:00 2001 From: Jean-Christian Denis Date: Tue, 24 Aug 2021 01:55:52 +0200 Subject: [PATCH] initial commit --- CHANGELOG | 88 +++++ LICENSE | 339 ++++++++++++++++ README.md | 30 ++ _admin.php | 62 +++ _config.php | 131 +++++++ _define.php | 36 ++ _install.php | 105 +++++ _prepend.php | 23 ++ _public.php | 112 ++++++ _uninstall.php | 59 +++ _widgets.php | 221 +++++++++++ icon-big.png | Bin 0 -> 2863 bytes icon.png | Bin 0 -> 636 bytes inc/lib.epc.php | 800 ++++++++++++++++++++++++++++++++++++++ inc/lib.epc.records.php | 225 +++++++++++ inc/lib.epc.update.php | 44 +++ index.php | 441 +++++++++++++++++++++ locales/en/help/help.html | 19 + locales/en/resources.php | 18 + locales/fr/help/help.html | 20 + locales/fr/main.lang.php | 215 ++++++++++ locales/fr/main.po | 291 ++++++++++++++ locales/fr/resources.php | 18 + 23 files changed, 3297 insertions(+) create mode 100644 CHANGELOG create mode 100644 LICENSE create mode 100644 README.md create mode 100644 _admin.php create mode 100644 _config.php create mode 100644 _define.php create mode 100644 _install.php create mode 100644 _prepend.php create mode 100644 _public.php create mode 100644 _uninstall.php create mode 100644 _widgets.php create mode 100644 icon-big.png create mode 100644 icon.png create mode 100644 inc/lib.epc.php create mode 100644 inc/lib.epc.records.php create mode 100644 inc/lib.epc.update.php create mode 100644 index.php create mode 100644 locales/en/help/help.html create mode 100644 locales/en/resources.php create mode 100644 locales/fr/help/help.html create mode 100644 locales/fr/main.lang.php create mode 100644 locales/fr/main.po create mode 100644 locales/fr/resources.php diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..45f8162 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,88 @@ +enhancePostContent xxxx.xx.xx +=========================================================== + * Not added priority on filters for replacement order + * Not added priority on lists of filters for replacement order + * Not added auto-find post title in content + +enhancePostContent 2013.11.08 +=========================================================== + * Switch to Dotclear 2.6 (admin styles and settings) + * Add dashboard icon + * Add widget options (content_only and class) + * Fix records list pager + +enhancePostContent 2013.06.25 +=========================================================== + * Fixed widget compatibility for php 5.4 + +enhancePostContent 2013.05.11 +=========================================================== + * Fixed bug with Twitter replacement and wiki synthax of blockquote + * Fixed page title + +enhancePostContent 2011.06.03 +=========================================================== + * Added 'feeds pages' + +enhancePostContent 0.9 - 2010-06-06 +=========================================================== + * Switched to DC 2.2 + +enhancePostContent 0.8.1 - 2010-03-31 +=========================================================== + * Fixed some l10n + * Added option for default list order + +enhancePostContent 0.8 - 2010-03-31 +=========================================================== + * Added admin lists sortable + * Added pager for admin lists + * Added update on records + * Changed title of HTML tag on links replacement + * Removed empty CSS from head + * Enhanced admin pages + +enhancePostContent 0.7 - 2010-01-12 +=========================================================== + * Moved lists from setting to a new database + +enhancePostContent 0.6 - 2010-01-09 +=========================================================== + * Fixed HTML tags to use standard tags. + * Fixed CSS class names + * Changed settings management + * Added widget (only for post page) + * Added some post enhancement + +enhancePostContent 0.5 - 2009-12-28 +=========================================================== + * Added support of comment content + * Added support of word replacement + * Added option for case sensitive + * Added option for plural + * Changed class from post-xxx to epc-xxx + * Changed names from acronyme to acronym + * Changed acronym html tag from to + * Changed all settings management + +enhancePostContent 0.4 - 2009-12-24 +=========================================================== + * Merry Christmas! + * enhanced filters + * Added support of entry excerpt + * Added support of custom ignored HTML tags + * Added some help + +enhancePostContent 0.3 - 2009-12-21 +=========================================================== + * Fixed filter with punctuation (slow hack) + * Added word-to-link filter + +enhancePostContent 0.2 - 2009-12-12 +=========================================================== + * Fixed case sensitive definition + * Prepared DC 2.2 + +enhancePostContent 0.1 - 2009-10-17 +=========================================================== + * First release \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + 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 Lesser 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. + + GNU GENERAL PUBLIC LICENSE + 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. + + + Copyright (C) + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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. + + , 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 Lesser General +Public License instead of this License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..574c59d --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# README + +## WHAT IS ENHANCEPOSTCONTENT ? + +"Enhance Post Content" is a plugin for the open-source +web publishing software called Dotclear. + +It help to filter post content and extract or +show inline more info about words and expressions such as +atgs, acronyms, abbreviations, definition, citation, link, etc... + +## REQUIREMENTS + + enhancePostContent requires: + + * admin permissions to set up plugin + * content admin permissions to manage fitlers + * Dotclear 2.6 + +## USAGE + +First install enhancePostContent, manualy from a zip package or from +Dotaddict repository. (See Dotclear's documentation to know how do this) + +Go to ''plugins manager'', expand enhancePostContent information then +go to ''configure plugin'', fill in form. + +Once it's done you can manage filters from menu +''Enhance Post Content'' on sidebar or you can add dashboard icon, +you should also add widgets. \ No newline at end of file diff --git a/_admin.php b/_admin.php new file mode 100644 index 0000000..331b777 --- /dev/null +++ b/_admin.php @@ -0,0 +1,62 @@ +addItem( + __('Enhance post content'), + 'plugin.php?p=enhancePostContent', + 'index.php?pf=enhancePostContent/icon.png', + preg_match( + '/plugin.php\?p=enhancePostContent(&.*)?$/', + $_SERVER['REQUEST_URI'] + ), + $core->auth->check('contentadmin', $core->blog->id) +); + +$core->addBehavior( + 'adminDashboardFavorites', + array('epcAdminBehaviors', 'adminDashboardFavorites') +); + +class epcAdminBehaviors +{ + public static function adminDashboardFavorites($core, $favs) + { + $favs->register('enhancePostContent', array( + 'title' => __('Enhance post content'), + 'url' => 'plugin.php?p=enhancePostContent', + 'small-icon' => 'index.php?pf=enhancePostContent/icon.png', + 'large-icon' => 'index.php?pf=enhancePostContent/icon-big.png', + 'permissions' => $core->auth->check('contentadmin', $core->blog->id), + 'active_cb' => array( + 'epcAdminBehaviors', + 'adminDashboardFavoritesActive' + ) + )); + } + + public static function adminDashboardFavoritesActive($request, $params) + { + return $request == 'plugin.php' + && isset($params['p']) + && $params['p'] == 'enhancePostContent'; + } +} diff --git a/_config.php b/_config.php new file mode 100644 index 0000000..8ee2717 --- /dev/null +++ b/_config.php @@ -0,0 +1,131 @@ +getURL().'#plugins' : $_REQUEST['redir']; + +# -- Form combos -- +$sortby_combo = array( + __('Date') => 'epc_upddt', + __('Key') => 'epc_key', + __('Value') => 'epc_value', + __('ID') => 'epc_id' +); + +$order_combo = array( + __('Ascending') => 'asc', + __('Descending') => 'desc' +); + +# -- Get settings -- +$core->blog->settings->addNamespace('enhancePostContent'); +$s = $core->blog->settings->enhancePostContent; +$active = (boolean) $s->enhancePostContent_active; +$list_sortby = (string) $s->enhancePostContent_list_sortby; +$list_order = (string) $s->enhancePostContent_list_order; +$list_nb = (integer) $s->enhancePostContent_list_nb; +$_filters = libEPC::blogFilters(); +$allowedtplvalues = libEPC::blogAllowedTplValues(); +$allowedpubpages = libEPC::blogAllowedPubPages(); + +# -- Set settings -- +if (!empty($_POST['save'])) { + + try { + $active = !empty($_POST['active']); + $list_sortby = in_array($_POST['list_sortby'], $sortby_combo) ? + $_POST['list_sortby'] : 'epc_id'; + $list_order = in_array($_POST['list_order'], $order_combo) ? + $_POST['list_order'] : 'desc'; + $list_nb = isset($_POST['list_nb']) && $_POST['list_nb'] > 0 ? + $_POST['list_nb'] : 20; + + $s->put('enhancePostContent_active', $active); + $s->put('enhancePostContent_list_sortby', $list_sortby); + $s->put('enhancePostContent_list_order', $list_order); + $s->put('enhancePostContent_list_nb', $list_nb); + + $allowedtplvalues = libEPC::explode($_POST['allowedtplvalues']); + $allowedpubpages = libEPC::explode($_POST['allowedpubpages']); + + $s->put( + 'enhancePostContent_allowedtplvalues', + serialize($allowedtplvalues) + ); + $s->put( + 'enhancePostContent_allowedpubpages', + serialize($allowedpubpages) + ); + + $core->blog->triggerBlog(); + + dcPage::addSuccessNotice( + __('Configuration has been successfully updated.') + ); + http::redirect( + $list->getURL('module=enhancePostContent&conf=1&redir='. + $list->getRedir()) + ); + } + catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +# -- Display form -- +echo ' + +
+

'.__('General').'

+

'.__('This enable public widgets and contents filter.').'

+ +

+ +
+ +
+

'.__('Record list').'

+

'.__('This is the default order of records lists.').'

+ +

'. +form::combo('list_sortby', $sortby_combo, $list_sortby).'

+ +

'. +form::combo('list_order', $order_combo, $list_order).'

+ +

'. +form::field('list_nb', 3, 3, $list_nb).'

+ +
+ +
+

'.__('Extra').'

+

'.__('This is a special feature to edit list of allowed template values and public pages where this plugin works.').'

+ +

'. +form::field('allowedtplvalues', 100,0, libEPC::implode($allowedtplvalues)).'

+

'.__('Use "readable_name1:template_value1;readable_name2:template_value2;" like "entry content:EntryContent;entry excerpt:EntryExcerpt;".').'

+ +

'. +form::field('allowedpubpages', 100, 0, libEPC::implode($allowedpubpages)).'

+

'.__('Use "readable_name1:template_page1;readable_name2:template_page2;" like "post page:post.html;home page:home.html;".').'

+ +
'; diff --git a/_define.php b/_define.php new file mode 100644 index 0000000..a93d0d1 --- /dev/null +++ b/_define.php @@ -0,0 +1,36 @@ +registerModule( + /* Name */ + "Enhance post content", + /* Description*/ + "Add features to words in post content", + /* Author */ + "Jean-Christian Denis", + /* Version */ + '2013.11.08', + array( + 'permissions' => 'contentadmin', + 'type' => 'plugin', + 'dc_min' => '2.6', + 'support' => 'http://jcd.lv/q=enhancePostContent', + 'details' => 'http://plugins.dotaddict.org/dc2/details/enhancePostContent' + ) +); diff --git a/_install.php b/_install.php new file mode 100644 index 0000000..ee580b2 --- /dev/null +++ b/_install.php @@ -0,0 +1,105 @@ +plugins->moduleInfo($mod_id, 'version'); +$old_version = $core->getVersion($mod_id); + +if (version_compare($old_version, $new_version, '>=')) { + + return null; +} + +try +{ + # Check Dotclear version + if (!method_exists('dcUtils', 'versionsCompare') + || dcUtils::versionsCompare(DC_VERSION, $dc_min, '<', false)) { + throw new Exception(sprintf( + '%s requires Dotclear %s', $mod_id, $dc_min + )); + } + + # Database + $s = new dbStruct($core->con, $core->prefix); + $s->epc + ->epc_id ('bigint', 0, false) + ->blog_id ('varchar', 32, false) + ->epc_type('varchar', 32, false, "'epc'") + ->epc_filter('varchar', 64, false) + ->epc_key('varchar', 255, false) + ->epc_value('text', 0, false) + ->epc_upddt('timestamp', 0, false, 'now()') + + ->primary('pk_epc', 'epc_id') + ->index('idx_epc_blog_id', 'btree', 'blog_id') + ->index('idx_epc_type', 'btree', 'epc_type') + ->index('idx_epc_filter', 'btree', 'epc_filter') + ->index('idx_epc_key', 'btree', 'epc_key'); + + $si = new dbStruct($core->con, $core->prefix); + $changes = $si->synchronize($s); + $s = null; + + # Settings + $core->blog->settings->addNamespace($mod_id); + $s = $core->blog->settings->enhancePostContent; + + $s->put('enhancePostContent_active', false,'boolean', 'Enable enhancePostContent', false, true); + $s->put('enhancePostContent_list_sortby', 'epc_key', 'string', 'Admin records list field order', false, true); + $s->put('enhancePostContent_list_order', 'desc', 'string', 'Admin records list order', false, true); + $s->put('enhancePostContent_list_nb', 20, 'integer', 'Admin records list nb per page', false, true); + $s->put('enhancePostContent_allowedtplvalues', serialize(libEPC::defaultAllowedTplValues()), 'string', 'List of allowed template values', false, true); + $s->put('enhancePostContent_allowedpubpages', serialize(libEPC::defaultAllowedPubPages()), 'string', 'List of allowed template pages', false, true); + + # Filters settings + $filters = libEPC::defaultFilters(); + foreach($filters as $name => $filter) { + # Only editable options + $opt = array( + 'nocase' => $filter['nocase'], + 'plural' => $filter['plural'], + 'style' => $filter['style'], + 'notag' => $filter['notag'], + 'tplValues' => $filter['tplValues'], + 'pubPages' => $filter['pubPages'] + ); + $s->put('enhancePostContent_'.$name, serialize($opt), 'string', 'Settings for '.$name, false, true); + # only tables + if (isset($filter['list'])) { + $s->put('enhancePostContent_'.$name.'List', serialize($filter['list']), 'string', 'List for '.$name, false, true); + } + } + + # Move old filters lists from settings to database + if ($old_version && version_compare('0.6.6', $old_version, '>=')) { + include_once dirname(__FILE__).'/inc/lib.epc.update.php'; + } + + # Version + $core->setVersion($mod_id, $new_version); + + return true; +} +catch (Exception $e) { + $core->error->add($e->getMessage()); +} + +return false; diff --git a/_prepend.php b/_prepend.php new file mode 100644 index 0000000..82e4fe3 --- /dev/null +++ b/_prepend.php @@ -0,0 +1,23 @@ +blog->settings->addNamespace('enhancePostContent'); + +if ($core->blog->settings->enhancePostContent->enhancePostContent_active) { + + $core->addBehavior( + 'publicHeadContent', + array('publicEnhancePostContent', 'publicHeadContent') + ); + $core->addBehavior( + 'publicBeforeContentFilter', + array('publicEnhancePostContent', 'publicContentFilter') + ); +} + +/** + * @ingroup DC_PLUGIN_ENHANCEPOSTCONTENT + * @brief Filter posts content - public methods. + * @since 2.6 + */ +class publicEnhancePostContent +{ + /** + * Add filters CSS to page header + * + * @param dcCore $core dcCore instance + */ + public static function publicHeadContent(dcCore $core) + { + $filters = libEPC::blogFilters(); + + foreach($filters as $name => $filter) { + + if (empty($filter['class']) + || empty($filter['style']) + ) { + continue; + } + + $res = ''; + foreach($filter['class'] as $k => $class) { + $style = html::escapeHTML(trim($filter['style'][$k])); + if ('' != $style) { + $res .= $class." {".$style."} "; + } + } + + if (!empty($res)) { + echo + "\n \n". + " \n"; + } + } + } + + /** + * Filter template blocks content + * + * @param dcCore $core dcCore instance + * @param string $tag Tempalte block name + * @param array $args Tempalte Block arguments + */ + public static function publicContentFilter(dcCore $core, $tag, $args) + { + $filters = libEPC::blogFilters(); + $records = new epcRecords($core); + + foreach($filters as $name => $filter) { + + if (!isset($filter['publicContentFilter']) + || !is_callable($filter['publicContentFilter']) + || !libEPC::testContext($tag,$args,$filter) + ) { + continue; + } + + if ($filter['has_list']) { + $filter['list'] = $records->getRecords(array( + 'epc_filter' => $name) + ); + if ($filter['list']->isEmpty()) { + continue; + } + } + + call_user_func_array( + $filter['publicContentFilter'], + array($core, $filter, $tag, $args) + ); + } + } +} diff --git a/_uninstall.php b/_uninstall.php new file mode 100644 index 0000000..b793f86 --- /dev/null +++ b/_uninstall.php @@ -0,0 +1,59 @@ +addUserAction( + /* type */ 'settings', + /* action */ 'delete_all', + /* ns */ 'enhancePostContent', + /* description */ __('delete all settings') +); + +$this->addUserAction( + /* type */ 'plugins', + /* action */ 'delete', + /* ns */ 'enhancePostContent', + /* description */ __('delete plugin files') +); + +$this->addUserAction( + /* type */ 'versions', + /* action */ 'delete', + /* ns */ 'enhancePostContent', + /* description */ __('delete the version number') +); + + +$this->addDirectAction( + /* type */ 'settings', + /* action */ 'delete_all', + /* ns */ 'enhancePostContent', + /* description */ sprintf(__('delete all %s settings'),'enhancePostContent') +); + +$this->addDirectAction( + /* type */ 'plugins', + /* action */ 'delete', + /* ns */ 'enhancePostContent', + /* description */ sprintf(__('delete %s plugin files'),'enhancePostContent') +); + +$this->addDirectAction( + /* type */ 'versions', + /* action */ 'delete', + /* ns */ 'enhancePostContent', + /* description */ sprintf(__('delete %s version number'),'enhancePostContent') +); +?> \ No newline at end of file diff --git a/_widgets.php b/_widgets.php new file mode 100644 index 0000000..18c38a3 --- /dev/null +++ b/_widgets.php @@ -0,0 +1,221 @@ +addBehavior( + 'initWidgets', + array('enhancePostContentWidget', 'adminContentList') +); + +/** + * @ingroup DC_PLUGIN_ENHANCEPOSTCONTENT + * @brief Filter posts content - widgets methods. + * @since 2.6 + */ +class enhancePostContentWidget +{ + /** + * Admin part for widget that show extracted content + * + * @param dcWidgets $w dcWidgets instance + */ + public static function adminContentList($w) + { + global $core; + + $w->create( + 'epclist', + __('Enhance post content'), + array('enhancePostContentWidget', 'publicContentList'), + null, + __('List filtered contents.') + ); + # Title + $w->epclist->setting( + 'title', + __('Title:'), + __('In this article'), + 'text' + ); + # Text + $w->epclist->setting( + 'text', + __('Description:'), + '', + 'text' + ); + # Type + $filters = libEPC::blogFilters(); + $types = array(); + foreach($filters as $name => $filter) + { + if (!isset($filter['widgetListFilter']) + || !is_callable($filter['widgetListFilter']) + ) { + continue; + } + + $types[__($name)] = $name; + } + $w->epclist->setting( + 'type', + __('Type:'), + 'Definition', + 'combo', + $types + ); + # Content + $contents = libEPC::defaultAllowedWidgetValues(); + foreach($contents as $k => $v) { + $w->epclist->setting( + 'content'.$v['id'], + sprintf(__('Enable filter on %s'), __($k)), + 1, + 'check' + ); + } + # Case sensitive + $w->epclist->setting( + 'nocase', + __('Search case insensitive'), + 0, + 'check' + ); + # Plural + $w->epclist->setting( + 'plural', + __('Search also plural'), + 0, + 'check' + ); + # Show count + $w->epclist->setting( + 'show_total', + __('Show the number of appearance'), + 1, + 'check' + ); + # widget option - content only + $w->epclist->setting( + 'content_only', + __('Content only'), + 0, + 'check' + ); + # widget option - additionnal CSS + $w->epclist->setting( + 'class', + __('CSS class:'), + '' + ); + } + + /** + * Public part for widget that show extracted content + * + * @param dcWidget $w dcWidget instance + */ + public static function publicContentList($w) + { + global $core, $_ctx; + + $core->blog->settings->addNamespace('enhancePostContent'); + + # Page + if (!$core->blog->settings->enhancePostContent->enhancePostContent_active + || !in_array($_ctx->current_tpl,array('post.html','page.html')) + ) { + return null; + } + + # Content + $content = ''; + $allowedwidgetvalues = libEPC::defaultAllowedWidgetValues(); + foreach($allowedwidgetvalues as $k => $v) { + + $ns = 'content'.$v['id']; + if ($w->$ns && is_callable($v['callback'])) { + + $content .= call_user_func_array( + $v['callback'], + array($core,$w) + ); + } + } + + if (empty($content)) { + + return null; + } + + # Filter + $list = array(); + $filters = libEPC::blogFilters(); + + if (isset($filters[$w->type]) + && isset($filters[$w->type]['widgetListFilter']) + && is_callable($filters[$w->type]['widgetListFilter']) + ) { + $filters[$w->type]['nocase'] = $w->nocase; + $filters[$w->type]['plural'] = $w->plural; + + if ($filters[$w->type]['has_list']) { + $records = new epcRecords($core); + $filters[$w->type]['list'] = $records->getRecords( + array('epc_filter' => $w->type) + ); + } + + call_user_func_array( + $filters[$w->type]['widgetListFilter'], + array($core, $filters[$w->type], $content, $w, &$list) + ); + } + + if (empty($list)) { + + return null; + } + + # Parse result + $res = ''; + foreach($list as $line) { + if (empty($line['matches'][0]['match'])) { + continue; + } + + $res .= + '
  • '.$line['matches'][0]['match']. + ($w->show_total ? ' ('.$line['total'].')' : ''). + '
  • '; + } + + if (empty($res)) { + + return null; + } + + return + ($w->content_only ? '' : '
    '). + ($w->title ? '

    '.html::escapeHTML($w->title).'

    ' : ''). + ($w->text ? '

    '.html::escapeHTML($w->text).'

    ' : ''). + '
      '.$res.'
    '. + ($w->content_only ? '' : '
    '); + } +} diff --git a/icon-big.png b/icon-big.png new file mode 100644 index 0000000000000000000000000000000000000000..b5ce630a7c0702035ba7d0742c57d918b5e1a249 GIT binary patch literal 2863 zcmV+~3()k5P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qRNAp5A000V}NkljT?O{(*Z`%@25F@uxIb)FgW)I(Iv;AC>0XNElW5EV1qnMP*FPlkKF zcdU9J+;MvF=aF(87cQNgPK%iXnlsHV5VWMk@7NkY!%nql*24T_bJOcO z7oBUoy7aTA510Lc&$9M~wF$Yt0koJopgGg*LP1N#D=UM@g4LtOZ%uo7VQS6zf})Oz z*QY@(M8?~3@ z|El}7{D*<({X=ZM zeFLms#IYEwGA5a9kBTC2OU&Dq`}z_{j^0oq#^@$zgC>w>w*+7phc64Z@q*pYC_Xju zHthV52I9MAUxWA_5U;|W*NaE=iQh>SiEk0e9Tg>Qeic_fX%G71;T?CzY2H3G%&NM1wIYv&Ni8((3C zz%q%w0^{}sG=Vg`B@mkQ@(W?-AN6ZR9(1k&sfv}CscikGF76aRt;lGrp~x64Ap zOd;<6{*%*5TAgcgxW?TVj?{+Y5j24`yHtQoZogh-H!r1nd_J7|Zr1e3zY`K>3TrRR zNlC{vl2-l(3C|e25qbkx=4%W=6G*d50TjPMWj{X!j=a$N-l~CvkB~4^h$qI}=2uBl z(E{iO*OI_3wsI_!%vTwLCXi+~7kcq{-UsnFY2x9^_y&?*Z(+OV2l*#FF7cV!;C4in z~BdB?RH>VB+pk7GEWn|9eR4^!z1#?kI{A5{<+~sX+0tNC5@mx<$kB?D?25IH1MM0nM3ahagP5 z1=L#I&S8_|U!c&{dAzKJgd^GF1K~EoMdOPH>K>c(L5rCKnlsIA3Lx1HU$oZRE;t@a zUG?}JNMs*lLK6~>MDh3x5KAH?$U;n%m@t{?s1Ox1&6#GW0mVZjVz+6R16%wzLc;ar zh>sB`9w91bnlsIA4EmiHBOXg3BfdcF&g&s6W|}k2ZVU@nkK$bR)im+Y{uXykyaoOR z&=wC$JVI2=G-sL}6A>>l>DZU;^$BkQ^$LM99jXfbm@bLQLOzO-7r!P;$u z%I@dTdiqRD%R3`at08($*W~J&7G0BLq|PJF6%QQRTL8tc*fx4fM3&>G#0r419q`&_$U&QumK-0l@*-y zyjIaA`zv&7{}U2NBZ$`>X;FM|ytF&72TcjAhmb|O%n&koR78E4_76okm$?+l6!0>_UHz0X-%cB!|Q8u^6}Z9 zZ{SOI%-2W`W10+L%=zjK?W?(Ch-KHM9TJbB#P|ZQt zYFq?d9R8T+W&v2@&&L!xMXlUE8vj7S3h01~fL8+gu*V>u*#&6o%dNm1CDTzXr*gqa0MJE-_*S(cti$|88nnvQYmyn3Kh<^VeApIvZ>;cS2{lEn{ z{bAt^zW6BhDg*KOZ$&~7Nj)(4X<7jKkEYlIn2-8_3()gf$*C%>*SGuIfA+n)a;{E% zxPbUDm4c`;1IfN4vviBa7LN;3*fxX2WcibbSY`h>3)1wT&9MhEANAu_Z@22gMjQA3rcx{zd_7%SZ z!2f@MbHf+VMi*~}Ibe+NTUryrj#nsV(J(gImFrrEBW)#4fm>`H*~0Z$zS+iY$G&k} zpdy@O#2aLPe88FC=FtPYA7=C|t%+dAD-^S63}!N147ij%LHxSR2Dkc(PT3#%;_*tr zzwm_K|F^pjxTFWi+55ma<1Z>r06ShWF%O8rOcwCAt#fFS!;17nZk2er!F!x79*HN$ z>?Zfq38gNY^-*?y_*dV|aI?UUS4_+U0wxjt(^y4pB#F)lB)QEqN%h6a23fxpT4!~o zFHt70g^ID0D4934LUWl(Nq!nD`p40##59tbpGj(3vI%yId{#H_1$#P)-i;4aQUvFa zh?4$7+~g}ECNZ64<>iyg!&Ridwa$PAPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qRNAp5A0005&Nkl6GT_$Ts|=4`U*mlI<{DQDlVZjHZFb}2rY zxnJe~tQ{^{AoX}%VCu@oSTjc|boySU4?qL{P1>$_qkoISiSj;|H=#LvTwq1GU9juF zX=~g6{+-(YX98`{T
    vU=_3m{LI|pjzCq00K6C93Y!RfHuDe+1$HPeoI1?kT6sl z)wRe51ZVPbh*xj=V%paFzYl722GC}S>h-WN`HZXw3}BqBvc%i{o8=Eq-l=$R#y+L5 zP@6X=)gWw!0Sp7q-P$GCx5obejQvVKCTvkSJ@bI_A7E%dPO24>gepS;7zSK^v|C}; zZkw+q9X=mY^D|CP-mdnmZ@t#Hw7jB2AbBhpk(odOXRhz&X`X9o8koVy+qG715y%A{ zt7WG-26Hk&m4N|J?SCi}0YIifP2FGCoO6E8wy577b0dGI=q6H literal 0 HcmV?d00001 diff --git a/inc/lib.epc.php b/inc/lib.epc.php new file mode 100644 index 0000000..4812020 --- /dev/null +++ b/inc/lib.epc.php @@ -0,0 +1,800 @@ + 'EntryExcerpt', + 'entry content' => 'EntryContent', + 'comment content' => 'CommentContent', + ); + } + + public static function blogAllowedTplValues() + { + global $core; + $core->blog->settings->addNamespace('enhancePostContent'); + $allowedtplvalues = self::defaultAllowedTplValues(); + $rs = @unserialize($core->blog->settings->enhancePostContent->enhancePostContent_allowedtplvalues); + return is_array($rs) ? $rs : $allowedtplvalues; + } + + public static function defaultAllowedWidgetValues() + { + global $core; + + $rs = array( + 'entry excerpt' => array( + 'id' => 'entryexcerpt', + 'callback' => array('libEPC','widgetContentEntryExcerpt') + ), + 'entry content' => array( + 'id' => 'entrycontent', + 'callback' => array('libEPC','widgetContentEntryContent') + ), + 'comment content' => array( + 'id' => 'commentcontent', + 'callback' => array('libEPC','widgetContentCommentContent') + ) + ); + + $core->callBehavior('enhancePostContentAllowedWidgetValues',$rs); + + return $rs; + } + + public static function defaultAllowedPubPages() + { + return array( + 'home page' => 'home.html', + 'post page' => 'post.html', + 'category page' => 'category.html', + 'search results page' => 'search.html', + 'atom feeds' => 'atom.xml', + 'RSS feeds' => 'rss2.xml' + ); + } + + public static function blogAllowedPubPages() + { + global $core; + $core->blog->settings->addNamespace('enhancePostContent'); + $allowedpubpages = self::defaultAllowedPubPages(); + $rs = @unserialize($core->blog->settings->enhancePostContent->enhancePostContent_allowedpubpages); + return is_array($rs) ? $rs : $allowedpubpages; + } + + public static function defaultFilters() + { + global $core; + + $filters = array( + 'Tag' => array( + 'id' => 'tag', + 'publicContentFilter' => array('libEPC','publicContentFilterTag'), + 'widgetListFilter' => array('libEPC','widgetListTag'), + + 'help' => __('Highlight tags of your blog.'), + 'has_list' => false, + 'htmltag' => 'a', + 'class' => array('a.epc-tag'), + 'replace' => '%s', + 'widget' => '%s', + + 'nocase' => false, + 'plural' => false, + 'limit' => 0, + 'style' => array('text-decoration: none; border-bottom: 3px double #CCCCCC;'), + 'notag' => 'a,h1,h2,h3', + 'tplValues' => array('EntryContent'), + 'pubPages' => array('post.html') + ), + 'Search' => array( + 'id' => 'search', + 'publicContentFilter' => array('libEPC','publicContentFilterSearch'), + + 'help' => __('Highlight searched words.'), + 'has_list' => false, + 'htmltag' => '', + 'class' => array('span.epc-search'), + 'replace' => '%s', + + 'nocase' => true, + 'plural' => true, + 'limit' => 0, + 'style' => array('color: #FFCC66;'), + 'notag' => 'h1,h2,h3', + 'tplValues' => array('EntryContent'), + 'pubPages' => array('search.html') + ), + 'Acronym' => array( + 'id' => 'acronym', + 'publicContentFilter' => array('libEPC','publicContentFilterAcronym'), + 'widgetListFilter' => array('libEPC','widgetListAcronym'), + + 'help' => __('Explain some acronyms. First term of the list is the acornym and second term the explanation.'), + 'has_list' => true, + 'htmltag' => 'acronym', + 'class' => array('acronym.epc-acronym'), + 'replace' => '%s', + 'widget' => '%s', + + 'nocase' => false, + 'plural' => false, + 'limit' => 0, + 'style' => array('font-weight: bold;'), + 'notag' => 'a,acronym,abbr,dfn,h1,h2,h3', + 'tplValues' => array('EntryContent'), + 'pubPages' => array('post.html'), + ), + 'Abbreviation' => array( + 'id' => 'abbreviation', + 'publicContentFilter' => array('libEPC','publicContentFilterAbbreviation'), + 'widgetListFilter' => array('libEPC','widgetListAbbreviation'), + + 'help' => __('Explain some abbreviation. First term of the list is the abbreviation and second term the explanation.'), + 'has_list' => true, + 'htmltag' => 'a', + 'class' => array('abbr.epc-abbr'), + 'replace' => '%s', + 'widget' => '%s', + + 'nocase' => false, + 'plural' => false, + 'limit' => 0, + 'style' => array('font-weight: bold;'), + 'notag' => 'a,acronym,abbr,dfn,h1,h2,h3', + 'tplValues' => array('EntryContent'), + 'pubPages' => array('post.html'), + ), + 'Definition' => array( + 'id' => 'definition', + 'publicContentFilter' => array('libEPC','publicContentFilterDefinition'), + 'widgetListFilter' => array('libEPC','widgetListDefinition'), + + 'help' => __('Explain some definition. First term of the list is the sample to define and second term the explanation.'), + 'has_list' => true, + 'htmltag' => 'dfn', + 'class' => array('dfn.epc-dfn'), + 'replace' => '%s', + 'widget' => '%s', + + 'nocase' => false, + 'plural' => false, + 'limit' => 0, + 'style' => array('font-weight: bold;'), + 'notag' => 'a,acronym,abbr,dfn,h1,h2,h3', + 'tplValues' => array('EntryContent'), + 'pubPages' => array('post.html'), + ), + 'Citation' => array( + 'id' => 'citation', + 'publicContentFilter' => array('libEPC','publicContentFilterCitation'), + 'widgetListFilter' => array('libEPC','widgetListCitation'), + + 'help' => __('Highlight citation of people. First term of the list is the citation and second term the author.'), + 'has_list' => true, + 'htmltag' => 'cite', + 'class' => array('cite.epc-cite'), + 'replace' => '%s', + 'widget' => '%s', + + 'nocase' => true, + 'plural' => false, + 'limit' => 0, + 'style' => array('font-style: italic;'), + 'notag' => 'a,h1,h2,h3', + 'tplValues' => array('EntryContent'), + 'pubPages' => array('post.html'), + ), + 'Link' => array( + 'id' => 'link', + 'publicContentFilter' => array('libEPC','publicContentFilterLink'), + 'widgetListFilter' => array('libEPC','widgetListLink'), + + 'help' => __('Link some words. First term of the list is the term to link and second term the link.'), + 'has_list' => true, + 'htmltag' => 'a', + 'class' => array('a.epc-link'), + 'replace' => '%s', + 'widget' => '%s', + + 'nocase' => false, + 'plural' => false, + 'limit' => 0, + 'style' => array('text-decoration: none; font-style: italic; color: #0000FF;'), + 'notag' => 'a,h1,h2,h3', + 'tplValues' => array('EntryContent'), + 'pubPages' => array('post.html'), + ), + 'Replace' => array( + 'id' => 'replace', + 'publicContentFilter' => array('libEPC','publicContentFilterReplace'), + + 'help' => __('Replace some text. First term of the list is the text to replace and second term the replacement.'), + 'has_list' => true, + 'htmltag' => '', + 'class' => array('span.epc-replace'), + 'replace' => '%s', + + 'nocase' => true, + 'plural' => true, + 'limit' => 0, + 'style' => array('font-style: italic;'), + 'notag' => 'h1,h2,h3', + 'tplValues' => array('EntryContent'), + 'pubPages' => array('post.html'), + ), + 'Update' => array( + 'id' => 'update', + 'publicContentFilter' => array('libEPC','publicContentFilterUpdate'), + + 'help' => __('Update and show terms. First term of the list is the term to update and second term the new term.'), + 'has_list' => true, + 'htmltag' => 'del,ins', + 'class' => array('del.epc-update','ins.epc-update'), + 'replace' => '%s %s', + + 'nocase' => true, + 'plural' => true, + 'limit' => 0, + 'style' => array('text-decoration: line-through;','font-style: italic;'), + 'notag' => 'h1,h2,h3', + 'tplValues' => array('EntryContent'), + 'pubPages' => array('post.html'), + ), + 'Twitter' => array( + 'id' => 'twitter', + 'publicContentFilter' => array('libEPC','publicContentFilterTwitter'), + + 'help' => __('Add link to twitter user page. Every word started with "@" will be considered as twitter user.'), + 'has_list' => false, + 'htmltag' => 'a', + 'class' => array('a.epc-twitter'), + 'replace' => '', + + 'nocase' => false, + 'plural' => false, + 'limit' => 0, + 'style' => array('text-decoration: none; font-weight: bold; font-style: italic; color: #0000FF;'), + 'notag' => 'a,h1,h2,h3', + 'tplValues' => array('EntryContent'), + 'pubPages' => array('post.html') + ) + ); + + $core->callBehavior('enhancePostContentDefaultFilters',$filters); + + return $filters; + } + + public static function blogFilters($one=null) + { + global $core; + $core->blog->settings->addNamespace('enhancePostContent'); + $filters = self::defaultFilters(); + + foreach($filters as $name => $filter) + { + # Parse filters options + $ns = 'enhancePostContent_'.$name; + $opt[$name] = @unserialize($core->blog->settings->enhancePostContent->$ns); + + if (!is_array($opt[$name])) + { + $opt[$name] = array(); + } + if (isset($opt[$name]['nocase'])) + { + $filters[$name]['nocase'] = (boolean) $opt[$name]['nocase']; + } + if (isset($opt[$name]['plural'])) + { + $filters[$name]['plural'] = (boolean) $opt[$name]['plural']; + } + if (isset($opt[$name]['limit'])) + { + $filters[$name]['limit'] = abs((integer) $opt[$name]['limit']); + } + if (isset($opt[$name]['style']) && is_array($opt[$name]['style'])) + { + $filters[$name]['style'] = (array) $opt[$name]['style']; + } + if (isset($opt[$name]['notag'])) + { + $filters[$name]['notag'] = (string) $opt[$name]['notag']; + } + if (isset($opt[$name]['tplValues'])) + { + $filters[$name]['tplValues'] = (array) $opt[$name]['tplValues']; + } + if (isset($opt[$name]['pubPages'])) + { + $filters[$name]['pubPages'] = (array) $opt[$name]['pubPages']; + } + } + + $core->callBehavior('enhancePostContentBlogFilters',$filters); + + return $filters; + } + + public static function testContext($tag,$args,$opt) + { + return + isset($opt['pubPages']) + && is_array($opt['pubPages']) + && in_array($GLOBALS['_ctx']->current_tpl,$opt['pubPages']) + && isset($opt['tplValues']) + && is_array($opt['tplValues']) + && in_array($tag,$opt['tplValues']) + && $args[0] != '' //content + && !$args[2] // remove html + ; + } + + public static function replaceString($p,$r,$s,$filter,$before='\b',$after='\b') + { + # Limit + if ($filter['limit'] > 0) + { + $l = isset($GLOBALS['epcFilterLimit'][$filter['id']][$p]) ? $GLOBALS['epcFilterLimit'][$filter['id']][$p] : $filter['limit']; + if ($l < 1) return $s; + } else { + $l = -1; + } + # Case sensitive + $i = $filter['nocase'] ? 'i' : ''; + # Plural + $x = $filter['plural'] ? $p.'s|'.$p : $p; + # Mark words + $s = preg_replace('#('.$before.')('.$x.')('.$after.')#s'.$i,'$1ççççç$2ççççç$3',$s,-1,$count); + # Nothing to parse + if (!$count) return $s; + # Remove words that are into unwanted html tags + $tags = ''; + $ignore_tags = array_merge(self::decodeTags($filter['htmltag']),self::decodeTags($filter['notag'])); + if (is_array($ignore_tags) && !empty($ignore_tags)) + { + $tags = implode('|',$ignore_tags); + } + if (!empty($tags)) + { + $s = preg_replace_callback('#(<('.$tags.')[^>]*?>)(.*?)()#s',array('libEPC','removeTags'),$s); + } + # Remove words inside html tag (class, title, alt, href, ...) + $s = preg_replace('#(ççççç('.$p.'(s|))ççççç)(?=[^<]+>)#s'.$i,'$2$4',$s); + # Replace words by what you want (with limit) + $s = preg_replace('#ççççç('.$p.'(s|))ççççç#s'.$i,$r,$s,$l,$count); + # update limit + $GLOBALS['epcFilterLimit'][$filter['id']][$p] = $l - $count; + # Clean rest + return $s = preg_replace('#ççççç(.*?)ççççç#s','$1',$s); + } + + public static function matchString($p,$r,$s,$filter,$before='\b',$after='\b') + { + # Case sensitive + $i = $filter['nocase'] ? 'i' : ''; + # Plural + $x = $filter['plural'] ? $p.'s|'.$p : $p; + # Mark words + $t = preg_match_all('#'.$before.'('.$x.')'.$after.'#s'.$i,$s,$matches); + # Nothing to parse + if (!$t) return array('total'=>0,'matches'=>array()); + + # Build array + $m = array(); + $loop=0; + foreach($matches[1] as $match) + { + $m[$loop]['key'] = $match; + $m[$loop]['match'] = preg_replace('#('.$p.'(s|))#s'.$i,$r,$match,-1,$count); + $m[$loop]['num'] = $count; + $loop++; + } + return array('total'=>$t,'matches'=>$m); + } + + public static function quote($s) + { + return preg_quote($s,'#'); + } + + public static function removeTags($m) + { + return $m[1].preg_replace('#ççççç(?!ççççç)#s','$1',$m[3]).$m[4]; + } + + public static function decodeTags($t) + { + return preg_match_all('#([A-Za-z0-9]+)#',(string) $t, $m) ? $m[1] : array(); + } + + public static function implode($a) + { + if (is_string($a)) return $a; + if (!is_array($a)) return array(); + + $r = ''; + foreach($a as $k => $v) + { + $r .= $k.':'.$v.';'; + } + return $r; + } + + public static function explode($s) + { + if (is_array($s)) return $s; + if (!is_string($s)) return ''; + + $r = array(); + $s = explode(';',(string) $s); + if (!is_array($s)) return array(); + + foreach($s as $cpl) + { + $cur = explode(':',$cpl); + + if (!is_array($cur) || !isset($cur[1])) continue; + + $key = html::escapeHTML(trim($cur[0])); + $val = html::escapeHTML(trim($cur[1])); + + if (empty($key) || empty($val)) continue; + + $r[$key] = $val; + } + return $r; + } + + # + # Widgets + # + + public static function widgetContentEntryExcerpt($core,$w) + { + global $_ctx; + if (!$_ctx->exists('posts')) return; + + $res = ''; + while ($_ctx->posts->fetch()) + { + $res .= $_ctx->posts->post_excerpt; + } + return $res; + } + + public static function widgetContentEntryContent() + { + global $_ctx; + if (!$_ctx->exists('posts')) return; + + $res = ''; + while ($_ctx->posts->fetch()) + { + $res .= $_ctx->posts->post_content; + } + return $res; + } + + public static function widgetContentCommentContent() + { + global $core, $_ctx; + if (!$_ctx->exists('posts')) return; + + $res = ''; + $post_ids = array(); + while ($_ctx->posts->fetch()) + { + $comments = $core->blog->getComments(array('post_id'=>$_ctx->posts->post_id)); + while ($comments->fetch()) + { + $res .= $comments->getContent(); + } + } + return $res; + } + + # + # Filters + # + + public static function publicContentFilterTag($core,$filter,$tag,$args) + { + if (!$core->plugins->moduleExists('tags')) return; + + $metas = $core->meta->getMetadata(array('meta_type'=>'tag')); + + while($metas->fetch()) + { + $k = $metas->meta_id; + $args[0] = self::replaceString( + $k, + sprintf($filter['replace'],$core->blog->url.$core->url->getBase('tag').'/'.$k,'\\1'), + $args[0], + $filter + ); + } + return; + } + + public static function widgetListTag($core,$filter,$content,$w,&$list) + { + if (!$core->plugins->moduleExists('tags')) return; + + $metas = $core->meta->getMetadata(array('meta_type'=>'tag')); + + while($metas->fetch()) + { + $k = $metas->meta_id; + $list[] = self::matchString( + $k, + sprintf($filter['widget'],$core->blog->url.$core->url->getBase('tag').'/'.$k,'\\1'), + $content, + $filter + ); + } + return; + } + + public static function publicContentFilterSearch($core,$filter,$tag,$args) + { + if (!isset($GLOBALS['_search'])) return; + + $searchs = explode(' ',$GLOBALS['_search']); + + foreach($searchs as $k => $v) + { + $args[0] = self::replaceString( + $v, + sprintf($filter['replace'],'\\1'), + $args[0], + $filter + ); + } + return; + } + + public static function publicContentFilterAcronym($core,$filter,$tag,$args) + { + while($filter['list']->fetch()) + { + $k = $filter['list']->epc_key; + $v = $filter['list']->epc_value; + + $args[0] = self::replaceString( + $k, + sprintf($filter['replace'],__($v),'\\1'), + $args[0], + $filter + ); + } + return; + } + + public static function widgetListAcronym($core,$filter,$content,$w,&$list) + { + while($filter['list']->fetch()) + { + $k = $filter['list']->epc_key; + $v = $filter['list']->epc_value; + + $list[] = self::matchString( + $k, + sprintf($filter['widget'],__($v),'\\1'), + $content, + $filter + ); + } + return; + } + + public static function publicContentFilterAbbreviation($core,$filter,$tag,$args) + { + while($filter['list']->fetch()) + { + $k = $filter['list']->epc_key; + $v = $filter['list']->epc_value; + + $args[0] = self::replaceString( + $k, + sprintf($filter['replace'],__($v),'\\1'), + $args[0], + $filter + ); + } + return; + } + + public static function widgetListAbbreviation($core,$filter,$content,$w,&$list) + { + while($filter['list']->fetch()) + { + $k = $filter['list']->epc_key; + $v = $filter['list']->epc_value; + + $list[] = self::matchString( + $k, + sprintf($filter['widget'],__($v),'\\1'), + $content, + $filter + ); + } + return; + } + + public static function publicContentFilterDefinition($core,$filter,$tag,$args) + { + while($filter['list']->fetch()) + { + $k = $filter['list']->epc_key; + $v = $filter['list']->epc_value; + + $args[0] = self::replaceString( + $k, + sprintf($filter['replace'],__($v),'\\1'), + $args[0], + $filter + ); + } + return; + } + + public static function widgetListDefinition($core,$filter,$content,$w,&$list) + { + while($filter['list']->fetch()) + { + $k = $filter['list']->epc_key; + $v = $filter['list']->epc_value; + + $list[] = self::matchString( + $k, + sprintf($filter['widget'],__($v),'\\1'), + $content, + $filter + ); + } + return; + } + + public static function publicContentFilterCitation($core,$filter,$tag,$args) + { + while($filter['list']->fetch()) + { + $k = $filter['list']->epc_key; + $v = $filter['list']->epc_value; + + $args[0] = self::replaceString( + $k, + sprintf($filter['replace'],__($v),'\\1'), + $args[0], + $filter + ); + } + return; + } + + public static function widgetListCitation($core,$filter,$content,$w,&$list) + { + while($filter['list']->fetch()) + { + $k = $filter['list']->epc_key; + $v = $filter['list']->epc_value; + + $list[] = self::matchString( + $k, + sprintf($filter['widget'],__($v),'\\1'), + $content, + $filter + ); + } + return; + } + + public static function publicContentFilterLink($core,$filter,$tag,$args) + { + while($filter['list']->fetch()) + { + $k = $filter['list']->epc_key; + $v = $filter['list']->epc_value; + + $args[0] = self::replaceString( + $k, + sprintf($filter['replace'],'\\1',$v,'\\1'), + $args[0], + $filter + ); + } + return; + } + + public static function widgetListLink($core,$filter,$content,$w,&$list) + { + while($filter['list']->fetch()) + { + $k = $filter['list']->epc_key; + $v = $filter['list']->epc_value; + + $list[] = self::matchString( + $k, + sprintf($filter['widget'],$v,$v,'\\1'), + $content, + $filter + ); + } + return; + } + + public static function publicContentFilterReplace($core,$filter,$tag,$args) + { + while($filter['list']->fetch()) + { + $k = $filter['list']->epc_key; + $v = $filter['list']->epc_value; + + $args[0] = self::replaceString( + $k, + sprintf($filter['replace'],$v,'\\2'), + $args[0], + $filter + ); + } + return; + } + + public static function publicContentFilterUpdate($core,$filter,$tag,$args) + { + while($filter['list']->fetch()) + { + $k = $filter['list']->epc_key; + $v = $filter['list']->epc_value; + + $args[0] = self::replaceString( + $k, + sprintf($filter['replace'],'\\1',$v), + $args[0], + $filter + ); + } + return; + } + + public static function publicContentFilterTwitter($core,$filter,$tag,$args) + { + $args[0] = self::replaceString( + '[A-Za-z0-9_]{2,}', + sprintf($filter['replace'],'http://twitter.com/\\1','\\1'), + $args[0], + $filter, + '[^@]@','\b' + ); + return; + } +} +?> \ No newline at end of file diff --git a/inc/lib.epc.records.php b/inc/lib.epc.records.php new file mode 100644 index 0000000..f13d747 --- /dev/null +++ b/inc/lib.epc.records.php @@ -0,0 +1,225 @@ +core = $core; + $this->con = $core->con; + $this->table = $core->prefix.'epc'; + $this->blog = $core->con->escape($core->blog->id); + } + + public function getRecords($params,$count_only=false) + { + if ($count_only) + { + $strReq = 'SELECT count(E.epc_id) '; + } + else + { + $content_req = ''; + if (!empty($params['columns']) && is_array($params['columns'])) + { + $content_req .= implode(', ',$params['columns']).', '; + } + $strReq = + 'SELECT E.epc_id, E.blog_id, E.epc_type, E.epc_upddt, '. + $content_req. + 'E.epc_filter, E.epc_key, E.epc_value '; + } + + $strReq .= + 'FROM '.$this->table.' E '; + + if (!empty($params['from'])) + { + $strReq .= $params['from'].' '; + } + + $strReq .= "WHERE E.blog_id = '".$this->blog."' "; + + if (isset($params['epc_type'])) + { + if (is_array($params['epc_type']) && !empty($params['epc_type'])) + { + $strReq .= 'AND E.epc_type '.$this->con->in($params['epc_type']); + } + elseif ($params['epc_type'] != '') + { + $strReq .= "AND E.epc_type = '".$this->con->escape($params['epc_type'])."' "; + } + } + else + { + $strReq .= "AND E.epc_type = 'epc' "; + } + + if (isset($params['epc_filter'])) + { + if (is_array($params['epc_filter']) && !empty($params['epc_filter'])) + { + $strReq .= 'AND E.epc_filter '.$this->con->in($params['epc_filter']); + } + elseif ($params['epc_filter'] != '') + { + $strReq .= "AND E.epc_filter = '".$this->con->escape($params['epc_filter'])."' "; + } + } + + if (!empty($params['epc_id'])) + { + if (is_array($params['epc_id'])) + { + array_walk($params['epc_id'],create_function('&$v,$k','if($v!==null){$v=(integer)$v;}')); + } + else + { + $params['epc_id'] = array((integer) $params['epc_id']); + } + $strReq .= 'AND E.epc_id '.$this->con->in($params['epc_id']); + } + + if (!empty($params['sql'])) + { + $strReq .= $params['sql'].' '; + } + + if (!$count_only) + { + if (!empty($params['order'])) + { + $strReq .= 'ORDER BY '.$this->con->escape($params['order']).' '; + } + else + { + $strReq .= 'ORDER BY E.epc_key ASC '; + } + } + + if (!$count_only && !empty($params['limit'])) + { + $strReq .= $this->con->limit($params['limit']); + } + + return $this->con->select($strReq); + } + + public function addRecord($cur) + { + $this->con->writeLock($this->table); + + try + { + $cur->epc_id = $this->getNextId(); + $cur->blog_id = $this->blog; + $cur->epc_upddt = date('Y-m-d H:i:s'); + + $this->getCursor($cur); + + $cur->insert(); + $this->con->unlock(); + } + catch (Exception $e) + { + $this->con->unlock(); + throw $e; + } + $this->trigger(); + + # --BEHAVIOR-- enhancePostContentAfterAddRecord + $this->core->callBehavior('enhancePostContentAfterAddRecord',$cur); + + return $cur->epc_id; + } + + public function updRecord($id,$cur) + { + $id = (integer) $id; + + if (empty($id)) + { + throw new Exception(__('No such record ID')); + } + + $cur->epc_upddt = date('Y-m-d H:i:s'); + + $cur->update("WHERE epc_id = ".$id." AND blog_id = '".$this->blog."' "); + $this->trigger(); + + # --BEHAVIOR-- enhancePostContentAfterUpdRecord + $this->core->callBehavior('enhancePostContentAfterUpdRecord',$cur,$id); + } + + public function delRecord($id) + { + $id = (integer) $id; + + if (empty($id)) { + throw new Exception(__('No such record ID')); + } + + # --BEHAVIOR-- enhancePostContentBeforeDelRecord + $this->core->callBehavior('enhancePostContentbeforeDelRecord',$id); + + $this->con->execute( + 'DELETE FROM '.$this->table.' '. + 'WHERE epc_id = '.$id.' '. + "AND blog_id = '".$this->blog."' " + ); + + $this->trigger(); + } + + private function getNextId() + { + return $this->con->select( + 'SELECT MAX(epc_id) FROM '.$this->table.' ' + )->f(0) + 1; + } + + public function openCursor() + { + return $this->con->openCursor($this->table); + } + + private function getCursor($cur,$epc_id=null) + { + if ($cur->epc_key == '') + { + throw new Exception(__('No record key')); + } + if ($cur->epc_value == '') + { + throw new Exception(__('No record value')); + } + if ($cur->epc_filter == '') + { + throw new Exception(__('No record filter')); + } + $epc_id = is_int($epc_id) ? $epc_id : $cur->epc_id; + } + + private function trigger() + { + $this->core->blog->triggerBlog(); + } +} +?> \ No newline at end of file diff --git a/inc/lib.epc.update.php b/inc/lib.epc.update.php new file mode 100644 index 0000000..a5e4876 --- /dev/null +++ b/inc/lib.epc.update.php @@ -0,0 +1,44 @@ +con->select("SELECT * FROM ".$core->prefix."setting WHERE setting_ns='enhancePostContent' AND blog_id IS NOT NULL "); + +while ($f->fetch()) +{ + if (preg_match('#enhancePostContent_(.*?)List#',$f->setting_id,$m)) + { + $curlist = @unserialize($f->setting_value); + if (is_array($curlist)) + { + foreach($curlist as $k => $v) + { + $cur = $core->con->openCursor($core->prefix.'epc'); + $core->con->writeLock($core->prefix.'epc'); + + $cur->epc_id = $core->con->select('SELECT MAX(epc_id) FROM '.$core->prefix.'epc'.' ')->f(0) + 1; + $cur->blog_id = $f->blog_id; + $cur->epc_filter = $m[1]; + $cur->epc_key = $k; + $cur->epc_value = $v; + + $cur->insert(); + $core->con->unlock(); + } + } + $core->con->execute("DELETE FROM ".$core->prefix."setting WHERE setting_id='".$f->setting_id."' AND setting_ns='enhancePostContent' AND blog_id='".$f->blog_id."' "); + } +} +?> \ No newline at end of file diff --git a/index.php b/index.php new file mode 100644 index 0000000..8fe05c8 --- /dev/null +++ b/index.php @@ -0,0 +1,441 @@ +blog->settings->addNamespace('enhancePostContent'); +$s = $core->blog->settings->enhancePostContent; + +# -- Prepare queries and object -- + +$_filters = libEPC::blogFilters(); +$filters_id = array(); +foreach($_filters as $name => $filter) { + $filters_id[$filter['id']] = $name; +} + +$action = isset($_POST['action']) ? $_POST['action'] : ''; +$default_part = isset($_REQUEST['part']) ? $_REQUEST['part'] : key($filters_id); + +$records = new epcRecords($core); + +# -- Action -- + +if (!empty($action)) { + # --BEHAVIOR-- enhancePostContentAdminSave + $core->callBehavior('enhancePostContentAdminSave',$core); +} + +try +{ + # Update filter settings + if ($action == 'savefiltersetting' + && isset($filters_id[$default_part]) + ) { + # Parse filters options + $name = $filters_id[$default_part]; + $f = array( + 'nocase' => !empty($_POST['filter_nocase']), + 'plural' => !empty($_POST['filter_plural']), + 'limit' => abs((integer) $_POST['filter_limit']), + 'style' => (array) $_POST['filter_style'], + 'notag' => (string) $_POST['filter_notag'], + 'tplValues' => (array) $_POST['filter_tplValues'], + 'pubPages' => (array) $_POST['filter_pubPages'] + ); + + $s->put('enhancePostContent_'.$name, serialize($f)); + + $core->blog->triggerBlog(); + + dcPage::addSuccessNotice( + __('Filter successfully updated.') + ); + http::redirect( + $p_url.'part='.$default_part.'#setting' + ); + } + + # Add new filter record + if ($action == 'savenewrecord' + && isset($filters_id[$default_part]) + && !empty($_POST['new_key']) + && !empty($_POST['new_value']) + ) { + $cur = $records->openCursor(); + $cur->epc_filter = $filters_id[$default_part]; + $cur->epc_key = html::escapeHTML($_POST['new_key']); + $cur->epc_value = html::escapeHTML($_POST['new_value']); + $records->addRecord($cur); + + $core->blog->triggerBlog(); + + dcPage::addSuccessNotice( + __('Filter successfully updated.') + ); + http::redirect( + $p_url.'&part='.$default_part.'#record' + ); + } + + # Update filter records + if ($action == 'saveupdaterecords' + && isset($filters_id[$default_part]) + && $_filters[$filters_id[$default_part]]['has_list'] + ) { + foreach($_POST['epc_id'] as $k => $id) { + + $k = abs((integer) $k); + $id = abs((integer) $id); + + if (empty($_POST['epc_key'][$k]) + || empty($_POST['epc_value'][$k]) + ) { + $records->delRecord($id); + } + elseif ($_POST['epc_key'][$k] != $_POST['epc_old_key'][$k] + || $_POST['epc_value'][$k] != $_POST['epc_old_value'][$k] + ) { + $cur = $records->openCursor(); + $cur->epc_filter = $filters_id[$default_part]; + $cur->epc_key = html::escapeHTML($_POST['epc_key'][$k]); + $cur->epc_value = html::escapeHTML($_POST['epc_value'][$k]); + $records->updRecord($id,$cur); + } + } + + $core->blog->triggerBlog(); + + $redir = !empty($_REQUEST['redir']) ? + $_REQUEST['redir'] : + $p_url.'&part='.$default_part.'#record'; + + dcPage::addSuccessNotice( + __('Filter successfully updated.') + ); + http::redirect( + $redir + ); + } +} +catch(Exception $e) { + $core->error->add($e->getMessage()); +} + +# -- Prepare page -- + +$breadcrumb = array( + html::escapeHTML($core->blog->name) => '', + __('Enhance post content') => $p_url +); +$top_menu = array(); + +foreach($filters_id as $id => $name) { + + $active = ''; + if ($default_part == $id) { + $breadcrumb[__($filters_id[$default_part])] = ''; + $active = ' class="active"'; + } + + $top_menu[] = + ''.__($name).''; +} + +# -- Display page -- + +# Headers +echo ' +'.__('Enhance post content').''. +dcPage::jsLoad('js/_posts_list.js'). +dcPage::jsToolbar(). +dcPage::jsPageTabs(). + +# --BEHAVIOR-- enhancePostContentAdminHeader +$core->callBehavior('enhancePostContentAdminHeader',$core).' + +'. + +# Title +dcPage::breadcrumb($breadcrumb). +dcPage::notices(). + +# Filters list +'
      '. +'
    • '.implode('
    • ', $top_menu).'
    • '. +'
    '; + +# Filter content +if (isset($filters_id[$default_part])) { + + $name = $filters_id[$default_part]; + $filter = $_filters[$name]; + + # Filter title and description + echo ' +

    '.__($filters_id[$default_part]).'

    +

    '.$filter['help'].'

    '; + + # Filter settings + echo ' +
    +
    '; + + echo + '
    +

    '.__('Pages to be filtered').'

    '; + + foreach(libEPC::blogAllowedPubPages() as $k => $v) { + echo ' +

    '; + } + + echo + '
    '; + + echo + '
    +

    '.__('Filtering').'

    + +

    + +

    + +

    '. + form::field('filter_limit', 4, 10, html::escapeHTML($filter['limit'])).' +

    +

    '.__('Leave it blank or set it to 0 for no limit').'

    + +
    '; + + echo + '
    +

    '.__('Contents to be filtered').'

    '; + + foreach(libEPC::blogAllowedTplValues() as $k => $v) { + echo ' +

    '; + } + + echo + '
    '; + + echo + '
    +

    '.__('Style').'

    '; + + foreach($filter['class'] as $k => $v) { + echo ' +

    '. + form::field( + array('filter_style[]', 'filter_style'.$k), + 60, + 255, + html::escapeHTML($filter['style'][$k]) + ). + '

    '; + } + + echo ' +

    '.sprintf(__('The inserted HTML tag looks like: %s'), html::escapeHTML(str_replace('%s', '...', $filter['replace']))).'

    + +

    '. + form::field('filter_notag', 60, 255, html::escapeHTML($filter['notag'])).' +

    +

    '.__('This is the list of HTML tags where content will be ignored.').' '. + (empty($filter['htmltag']) ? '' : sprintf(__('Tag "%s" always be ignored.'), $filter['htmltag'])).'

    + +
    '; + + echo '
    +
    +

    '. + $core->formNonce(). + form::hidden(array('action'), 'savefiltersetting').' + +

    +
    + +
    +
    '; + + # Filter records list + if ($filter['has_list']) { + + $sortby_combo = array( + 'epc_upddt', + 'epc_key', + 'epc_value', + 'epc_id' + ); + + $order_combo = array( + 'asc', + 'desc' + ); + + $sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : (string) $s->enhancePostContent_list_sortby; + $order = !empty($_GET['order']) ? $_GET['order'] : (string) $s->enhancePostContent_list_order; + $page = !empty($_GET['page']) ? (integer) $_GET['page'] : 1; + $nb = !empty($_GET['nb']) && (integer) $_GET['nb'] > 0 ? (integer) $_GET['nb'] : (integer) $s->enhancePostContent_list_nb; + + $params = array(); + $params['epc_filter'] = $name; + $params['limit'] = array((($page-1)*$nb), $nb); + + if ($sortby !== '' && in_array($sortby, $sortby_combo)) { + if ($order !== '' && in_array($order, $order_combo)) { + $params['order'] = $sortby.' '.$order; + } + } + + try { + $list = $records->getRecords($params); + $counter = $records->getRecords($params, true); + } + catch (Exception $e) { + $core->error->add($e->getMessage()); + } + + $pager_url = $p_url. + '&nb='.$nb. + '&sortby=%s'. + '&order='.($order == 'desc' ? 'desc' : 'asc'). + '&page=%s'. + '&part='.$default_part. + '#record'; + + $pager = new pager($page, $counter->f(0), $nb, 10); + $pager->html_prev = __('«prev.'); + $pager->html_next = __('next»'); + $pager->base_url = sprintf($pager_url, $sortby,'%s'); + $pager->var_page = 'page'; + + echo ' +
    '; + + if ($core->error->flag() || $list->isEmpty()) { + echo '

    '.__('No record').'

    '; + } + else { + echo ' +
    +

    '.__('Page(s)').' : '.$pager->getLinks().'

    + + + + + + + '; + + while($list->fetch()) { + echo ' + + + + + '; + } + + echo ' + +
    ' + .__('Key').''. + __('Value').''. + __('Date').'
    '. + form::hidden(array('epc_id[]'), $list->epc_id). + form::hidden(array('epc_old_key[]'), html::escapeHTML($list->epc_key)). + form::hidden(array('epc_old_value[]'), html::escapeHTML($list->epc_value)). + form::field(array('epc_key[]'), 30, 225, html::escapeHTML($list->epc_key), '').''. + form::field(array('epc_value[]'), 90, 225, html::escapeHTML($list->epc_value), 'maximal').''. + dt::dt2str(__('%Y-%m-%d %H:%M'), $list->epc_upddt,$core->auth->getInfo('user_tz')).'
    +

    '.__('In order to remove a record, leave empty its key or value.').'

    +

    '.__('Page(s)').' : '.$pager->getLinks().'

    + +
    +

    '. + $core->formNonce(). + form::hidden(array('redir'), sprintf($pager_url, $sortby, $page)). + form::hidden(array('action'), 'saveupdaterecords').' + +

    +
    + +
    '; + } + + echo '
    '; + + # New record + echo ' +
    +
    '. + + '

    '. + form::field('new_key', 60, 255). + '

    '. + + '

    '. + form::field('new_value', 60, 255). + '

    + +

    '. + form::hidden(array('action'), 'savenewrecord'). + $core->formNonce().' + +

    +
    +
    '; + } +} + +# --BEHAVIOR-- enhancePostContentAdminPage +$core->callBehavior('enhancePostContentAdminPage',$core); + +dcPage::helpBlock('enhancePostContent'); + +# Footers +echo +'

    +'.__('Configuration').' - +enhancePostContent - '.$core->plugins->moduleInfo('enhancePostContent', 'version').'  +'.__('enhancePostContent').' +

    +'; \ No newline at end of file diff --git a/locales/en/help/help.html b/locales/en/help/help.html new file mode 100644 index 0000000..9cdfcfb --- /dev/null +++ b/locales/en/help/help.html @@ -0,0 +1,19 @@ + + + + + enhancePostContent + + + +

    If you want some help or contribute to the plugin enhancePostContent, follow these links.

    + + + + \ No newline at end of file diff --git a/locales/en/resources.php b/locales/en/resources.php new file mode 100644 index 0000000..005c37d --- /dev/null +++ b/locales/en/resources.php @@ -0,0 +1,18 @@ + \ No newline at end of file diff --git a/locales/fr/help/help.html b/locales/fr/help/help.html new file mode 100644 index 0000000..557413f --- /dev/null +++ b/locales/fr/help/help.html @@ -0,0 +1,20 @@ + + + + + enhancePostContent + + + +

    Support

    +

    Si vous souhaitez plus d'aide ou apporter votre contribution Ă  cette extension, voici quelques liens utiles.

    + + + + \ No newline at end of file diff --git a/locales/fr/main.lang.php b/locales/fr/main.lang.php new file mode 100644 index 0000000..11ba1aa --- /dev/null +++ b/locales/fr/main.lang.php @@ -0,0 +1,215 @@ + \ No newline at end of file diff --git a/locales/fr/main.po b/locales/fr/main.po new file mode 100644 index 0000000..7099609 --- /dev/null +++ b/locales/fr/main.po @@ -0,0 +1,291 @@ +# Language: Français +# Module: enhancePostContent - 2013.11.08 +# Date: 2013-11-09 05:21:10 +# Translated with translater 2013.05.11 + +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: enhancePostContent 2013.11.08\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2013-11-09T05:21:10+00:00\n" +"Last-Translator: Jean-Christian Denis\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" + +#: _admin.php:24 +#: _admin.php:44 +#: _widgets.php:43 +#: index.php:145 +#: index.php:165 +msgid "Enhance post content" +msgstr "AmĂ©lioration du contenu" + +#: _config.php:26 +#: index.php:361 +msgid "Key" +msgstr "ClĂ©" + +#: _config.php:79 +msgid "Configuration has been successfully updated." +msgstr "La configuration a Ă©tĂ© mise Ă  jour avec succĂ©s." + +#: _config.php:96 +msgid "This enable public widgets and contents filter." +msgstr "Ceci active les widgets et le filtrage du contenu en partie public." + +#: _config.php:100 +msgid "Enable plugin" +msgstr "Activer le plugin" + +#: _config.php:105 +msgid "Record list" +msgstr "Listes d'enregistrements" + +#: _config.php:106 +msgid "This is the default order of records lists." +msgstr "Ceci est l'ordre de trie par dĂ©faut des listes d'enregistrements." + +#: _config.php:114 +msgid "Records per page:" +msgstr "Enregistrements par page :" + +#: _config.php:121 +msgid "This is a special feature to edit list of allowed template values and public pages where this plugin works." +msgstr "Ceci est une option spĂ©ciale pour modifier les listes des balises de template et des pages publiques ou le plugin sera actif." + +#: _config.php:123 +msgid "Allowed DC template values:" +msgstr "Autoriser les balises de template :" + +#: _config.php:125 +msgid "Use \"readable_name1:template_value1;readable_name2:template_value2;\" like \"entry content:EntryContent;entry excerpt:EntryExcerpt;\"." +msgstr "Utiliser \"titre1:valeur_de_template1;titre2:valeur_de_template2;\" exemple \"entry content:EntreyContent;entry excerpt:EntreyExcerpt;\"." + +#: _config.php:127 +msgid "Allowed public pages:" +msgstr "Autoriser les pages publiques :" + +#: _config.php:129 +msgid "Use \"readable_name1:template_page1;readable_name2:template_page2;\" like \"post page:post.html;home page:home.html;\"." +msgstr "Utiliser \"titre1:page_de_template1;titre2:page_de_template2;\" comme \"post page:post.html;home page:home.html;\"." + +#: _widgets.php:46 +msgid "List filtered contents." +msgstr "Liste les contenus filtrĂ©s." + +#: _widgets.php:52 +msgid "In this article" +msgstr "Dans cet article" + +#: _widgets.php:87 +msgid "Enable filter on %s" +msgstr "Autoriser le filtrage sur %s" + +#: _widgets.php:95 +msgid "Search case insensitive" +msgstr "Recherche insensible Ă  la casse" + +#: _widgets.php:102 +msgid "Search also plural" +msgstr "Recherche Ă©galement le pluriel" + +#: _widgets.php:109 +msgid "Show the number of appearance" +msgstr "Afficher le nombre d'occurence" + +#: inc/lib.epc.php:16 +msgid "Acronym" +msgstr "Acronyme" + +#: inc/lib.epc.php:16 +msgid "Abbreviation" +msgstr "AbrĂ©viation" + +#: inc/lib.epc.php:16 +msgid "Definition" +msgstr "DĂ©finition" + +#: inc/lib.epc.php:17 +msgid "Citation" +msgstr "Citation" + +#: inc/lib.epc.php:17 +msgid "Replace" +msgstr "Remplacement" + +#: inc/lib.epc.php:18 +msgid "entry excerpt" +msgstr "le rĂ©sumĂ© du billet" + +#: inc/lib.epc.php:18 +msgid "entry content" +msgstr "le contenu du billet" + +#: inc/lib.epc.php:18 +msgid "comment content" +msgstr "le contenu des commentaires" + +#: inc/lib.epc.php:19 +msgid "home page" +msgstr "la page d'accueil" + +#: inc/lib.epc.php:19 +msgid "post page" +msgstr "la page du billet" + +#: inc/lib.epc.php:19 +msgid "category page" +msgstr "la page de catĂ©gorie" + +#: inc/lib.epc.php:19 +msgid "search results page" +msgstr "la page des rĂ©sultats de recherche" + +#: inc/lib.epc.php:20 +msgid "atom feeds" +msgstr "les flux Atom" + +#: inc/lib.epc.php:20 +msgid "RSS feeds" +msgstr "les flux RSS" + +#: inc/lib.epc.php:101 +msgid "Highlight tags of your blog." +msgstr "Met en avant les Tags de votre blog" + +#: inc/lib.epc.php:120 +msgid "Highlight searched words." +msgstr "Met en avant les mots recherchĂ©s" + +#: inc/lib.epc.php:139 +msgid "Explain some acronyms. First term of the list is the acornym and second term the explanation." +msgstr "Explique des acronymes. Le premier terme de la liste est l'acronyme et les second terme l'explication." + +#: inc/lib.epc.php:159 +msgid "Explain some abbreviation. First term of the list is the abbreviation and second term the explanation." +msgstr "Explique des abrĂ©viations. Le premier terme de la liste est l'abrĂ©viation et le second terme l'explication." + +#: inc/lib.epc.php:179 +msgid "Explain some definition. First term of the list is the sample to define and second term the explanation." +msgstr "Explique des dĂ©finitions. Le premier terme de la liste est la chaine Ă  expliquer et le second terme est la dĂ©finition." + +#: inc/lib.epc.php:199 +msgid "Highlight citation of people. First term of the list is the citation and second term the author." +msgstr "Met en avant les citation des gens. Le premier terme est la citation et le second terme est l'auteur." + +#: inc/lib.epc.php:219 +msgid "Link some words. First term of the list is the term to link and second term the link." +msgstr "Ajouter des liens. Le premier terme de la liste est le texte Ă  lier et le second terme est l'adresse de lien." + +#: inc/lib.epc.php:238 +msgid "Replace some text. First term of the list is the text to replace and second term the replacement." +msgstr "Remplace du texte. Le premier terme de la liste est le terme Ă  remplacer et le second le nouveau terme." + +#: inc/lib.epc.php:256 +msgid "Update and show terms. First term of the list is the term to update and second term the new term." +msgstr "Met Ă  jour du contenu. Le premier terme de la liste est l'ancien texte et le second le nouveau texte." + +#: inc/lib.epc.php:274 +msgid "Add link to twitter user page. Every word started with \"@\" will be considered as twitter user." +msgstr "Ajouter un lien vers une page Twitter. Chaque mot commençant par \"@\" sera considĂ©rĂ© comme un nom de compte Twitter" + +#: inc/lib.epc.php:278 +msgid "View this user's twitter page" +msgstr "Voir la page Twitter de cet utilisateur" + +#: index.php:68 +#: index.php:90 +#: index.php:130 +msgid "Filter successfully updated." +msgstr "Filtre mis Ă  jour." + +#: index.php:197 +msgid "Settings" +msgstr "Paramètres" + +#: index.php:202 +msgid "Pages to be filtered" +msgstr "Pages Ă  filtrer" + +#: index.php:220 +msgid "Filtering" +msgstr "Filtrage" + +#: index.php:224 +msgid "Case insensitive" +msgstr "Insensible Ă  la casse" + +#: index.php:228 +msgid "Also use the plural" +msgstr "Utiliser Ă©galement le pluriel" + +#: index.php:231 +msgid "Limit the number of replacement to:" +msgstr "Limiter le nombre de remplacement Ă  :" + +#: index.php:234 +msgid "Leave it blank or set it to 0 for no limit" +msgstr "Laisser vide ou mettre Ă  0 pour aucune limite" + +#: index.php:240 +msgid "Contents to be filtered" +msgstr "Contenus Ă  filtrer" + +#: index.php:258 +msgid "Style" +msgstr "Style" + +#: index.php:263 +msgid "Class \"%s\":" +msgstr "Class CSS \"%s\" :" + +#: index.php:274 +msgid "The inserted HTML tag looks like: %s" +msgstr "Le code HTML de la balise est le suivant: %s" + +#: index.php:276 +msgid "Ignore HTML tags:" +msgstr "Ignorer les balises HTML :" + +#: index.php:279 +msgid "This is the list of HTML tags where content will be ignored." +msgstr "Ceci est la liste des balises HTML dont le contenu sera ignorĂ©." + +#: index.php:280 +msgid "Tag \"%s\" always be ignored." +msgstr "Les balises \"%s\" seront toujours ignorĂ©es." + +#: index.php:343 +msgid "«prev." +msgstr "prĂ©c." + +#: index.php:344 +msgid "next»" +msgstr "suiv." + +#: index.php:349 +msgid "Records" +msgstr "Enregistrements" + +#: index.php:352 +msgid "No record" +msgstr "Pas d'enregistrement" + +#: index.php:387 +msgid "In order to remove a record, leave empty its key or value." +msgstr "Pour retirer un enregistrement, laisser vide sa clĂ© ou sa valeur." + +#: index.php:406 +msgid "New record" +msgstr "Nouvel enregistrement" + +#: index.php:409 +msgid "Key:" +msgstr "ClĂ© :" + +#: index.php:413 +msgid "Value:" +msgstr "Valeur :" + diff --git a/locales/fr/resources.php b/locales/fr/resources.php new file mode 100644 index 0000000..005c37d --- /dev/null +++ b/locales/fr/resources.php @@ -0,0 +1,18 @@ + \ No newline at end of file