commit 1d67937f38604858d4bc25e7a5d0581d8e8bc6e1 Author: Jean-Christian Denis Date: Thu Sep 9 00:53:13 2021 +0200 initial commit 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/_admin.php b/_admin.php new file mode 100644 index 0000000..871fbdf --- /dev/null +++ b/_admin.php @@ -0,0 +1,22 @@ +addItem( + __('Noodles'), + 'plugin.php?p=noodles','index.php?pf=noodles/icon.png', + preg_match('/plugin.php\?p=noodles(&.*)?$/',$_SERVER['REQUEST_URI']), + $core->auth->check('admin',$core->blog->id) +); +?> \ No newline at end of file diff --git a/_define.php b/_define.php new file mode 100644 index 0000000..220e10d --- /dev/null +++ b/_define.php @@ -0,0 +1,24 @@ +registerModule( + /* Name */ "Noodles", + /* Description*/ "Add users gravatars everywhere", + /* Author */ "JC Denis", + /* Version */ '0.6.1', + /* Permissions */ 'admin' + //* Priority */ 10000000 +); + /* date */ #20100705 +?> \ No newline at end of file diff --git a/_install.php b/_install.php new file mode 100644 index 0000000..93433d3 --- /dev/null +++ b/_install.php @@ -0,0 +1,40 @@ +plugins->moduleInfo('noodles','version'); +$old_version = $core->getVersion('noodles'); + +if (version_compare($old_version,$new_version,'>=')) return; + +try +{ + if (version_compare(DC_VERSION,'2.2-beta','<')) + { + throw new Exception('noodles requires Dotclear 2.2'); + } + + $core->blog->settings->addNamespace('noodles'); + + $core->blog->settings->noodles->put('noodles_active',false,'boolean','Enable extension',false,true); + + $core->setVersion('noodles',$new_version); + + return true; +} +catch (Exception $e) +{ + $core->error->add($e->getMessage()); +} +return false; +?> \ No newline at end of file diff --git a/_prepend.php b/_prepend.php new file mode 100644 index 0000000..71345e1 --- /dev/null +++ b/_prepend.php @@ -0,0 +1,27 @@ +blog->settings->addNamespace('noodles'); + +$core->url->register('noodlesmodule','noodles','^noodles/(.+)$', + array('urlNoodles','noodles')); +$core->url->register('noodlesservice','noodle','^noodle/$', + array('urlNoodles','service')); + +?> \ No newline at end of file diff --git a/_public.php b/_public.php new file mode 100644 index 0000000..83ecc11 --- /dev/null +++ b/_public.php @@ -0,0 +1,226 @@ +blog->settings->noodles->noodles_active) return; + +include dirname(__FILE__).'/inc/_default_noodles.php'; +require_once dirname(__FILE__).'/inc/_noodles_functions.php'; + +$core->addBehavior('publicHeadContent', + array('publicNoodles','publicHeadContent')); + +$core->tpl->setPath($core->tpl->getPath(),dirname(__FILE__).'/default-templates'); + +global $__noodles; +$__noodles = noodles::decode($core->blog->settings->noodles->noodles_object); + +if ($__noodles->isEmpty()) + $__noodles = $__default_noodles; + +//$GLOBALS['__noodles'] =& $__noodles; + +foreach($__noodles->noodles() AS $noodle) { + if ($noodle->active && $noodle->hasPhpCallback()) + $noodle->phpCallback($core); +} + +class publicNoodles +{ + public static function publicHeadContent($core) + { + $__noodles =& $GLOBALS['__noodles']; + + $css = "\n"; + $targets = array(); + foreach($__noodles->noodles() AS $noodle) { + + if (!$noodle->active || !$noodle->hasJsCallback()) continue; + + $css .= '.noodles-'.$noodle->id().'{'.$noodle->css.'}'."\n"; + + $targets[] = + ' $(\''.html::escapeJS($noodle->target).'\').noodles({'. + 'imgId:\''.html::escapeJS($noodle->id()).'\','. + 'imgPlace:\''.html::escapeJS($noodle->place).'\''. + '});'; + } + + if (empty($targets)) return; + + echo + "\n \n". + ''. + "\n \n". + " \n". + "\n"; + } +} + +class urlNoodles extends dcUrlHandlers +{ + public static function service($args) + { + global $core; + + header('Content-Type: text/xml; charset=UTF-8'); + + $rsp = new xmlTag('rsp'); + + $i = !empty($_POST['noodleId']) ? $_POST['noodleId'] : null; + $c = !empty($_POST['noodleContent']) ? $_POST['noodleContent'] : null; + + if (!$core->blog->settings->noodles->noodles_active) + { + $rsp->status = 'failed'; + $rsp->message(__('noodles is disabled on this blog')); + echo $rsp->toXML(1); + return false; + } + + if ($i === null || $c === null) + { + $rsp->status = 'failed'; + $rsp->message(__('noodles failed because of missing informations')); + echo $rsp->toXML(1); + return false; + } + + try + { + $__noodles = noodles::decode($core->blog->settings->noodles->noodles_object); + + if ($__noodles->isEmpty()) + { + $__noodles = $GLOBALS['__default_noodles']; + } + } + catch(Excetpion $e) + { + $rsp->status = 'failed'; + $rsp->message(__('Failed to load default noodles')); + echo $rsp->toXML(1); + return false; + } + + if (!$__noodles->exists($i)) + { + $rsp->status = 'failed'; + $rsp->message(__('Failed to load noodle')); + echo $rsp->toXML(1); + return false; + } + + $m = $__noodles->{$i}->jsCallback($__noodles->{$i},$c); + + $s = $__noodles->{$i}->size; + $r = $__noodles->{$i}->rating; + $d = $core->blog->settings->noodles->noodles_image ? + urlencode(noodlesLibImagePath::getUrl($core,'noodles')) : ''; + + if (!$m) $m = 'nobody@nowhere.tld'; + if (!$s) $s = 32; + if (!$r) $r = 'g'; + + $m = mb_strtolower($m); + $m = md5($m); + + $im = new xmlTag('noodle'); + $im->size = $s; + $im->src = 'http://www.gravatar.com/avatar/'.$m.'?s='.$s.'&r='.$r.'&d='.$d; + $rsp->insertNode($im); + + $rsp->status = 'ok'; + echo $rsp->toXML(1); + exit; + } + + public static function noodles($args) + { + global $core; + + if (!$core->blog->settings->noodles->noodles_active) + { + self::p404(); + return; + } + + if (!preg_match('#^(.*?)$#',$args,$m)) + { + self::p404(); + return; + } + + $f = $m[1]; + + if (!($f = self::searchTplFiles($f))) + { + self::p404(); + return; + } + + $allowed_types = array('png','jpg','jpeg','gif','css','js','swf'); + if (!in_array(files::getExtension($f),$allowed_types)) + { + self::p404(); + return; + } + $type = files::getMimeType($f); + + header('Content-Type: '.$type.'; charset=UTF-8'); + header('Content-Length: '.filesize($f)); + + if ($type != "text/css" || $core->blog->settings->system->url_scan == 'path_info') + { + readfile($f); + } + else + { + echo preg_replace('#url\((?!(http:)|/)#','url('.$core->blog->url.$core->url->getBase('noodlesmodule').'/',file_get_contents($f)); + } + exit; + } + + # Search noodles files like JS, CSS in default-templates subdirectories + private static function searchTplFiles($file) + { + if (strstr($file,"..") !== false) + { + return false; + } + $paths = $GLOBALS['core']->tpl->getPath(); + + foreach($paths as $path) + { + if (preg_match('/tpl(\/|)$/',$path)) + { + $path = path::real($path.'/..'); + } + if (file_exists($path.'/'.$file)) + { + return $path.'/'.$file; + } + } + return false; + } +} +?> \ No newline at end of file diff --git a/_uninstall.php b/_uninstall.php new file mode 100644 index 0000000..e836551 --- /dev/null +++ b/_uninstall.php @@ -0,0 +1,44 @@ +addUserAction( + /* type */ 'settings', + /* action */ 'delete_all', + /* ns */ 'noodles', + /* description */ __('delete all settings') +); + +$this->addUserAction( + /* type */ 'plugins', + /* action */ 'delete', + /* ns */ 'noodles', + /* description */ __('delete plugin files') +); + + +$this->addDirectAction( + /* type */ 'settings', + /* action */ 'delete_all', + /* ns */ 'noodles', + /* description */ sprintf(__('delete all %s settings'),'noodles') +); + +$this->addDirectAction( + /* type */ 'plugins', + /* action */ 'delete', + /* ns */ 'noodles', + /* description */ sprintf(__('delete %s plugin files'),'noodles') +); + +?> \ No newline at end of file diff --git a/default-templates/img/gravatar-01.png b/default-templates/img/gravatar-01.png new file mode 100644 index 0000000..1a53105 Binary files /dev/null and b/default-templates/img/gravatar-01.png differ diff --git a/default-templates/img/gravatar-02.png b/default-templates/img/gravatar-02.png new file mode 100644 index 0000000..15f8e2c Binary files /dev/null and b/default-templates/img/gravatar-02.png differ diff --git a/default-templates/img/gravatar-03.png b/default-templates/img/gravatar-03.png new file mode 100644 index 0000000..6b167bc Binary files /dev/null and b/default-templates/img/gravatar-03.png differ diff --git a/default-templates/img/gravatar-10.png b/default-templates/img/gravatar-10.png new file mode 100644 index 0000000..c289a5a Binary files /dev/null and b/default-templates/img/gravatar-10.png differ diff --git a/default-templates/img/gravatar-20.png b/default-templates/img/gravatar-20.png new file mode 100644 index 0000000..3505909 Binary files /dev/null and b/default-templates/img/gravatar-20.png differ diff --git a/default-templates/img/gravatar-30.png b/default-templates/img/gravatar-30.png new file mode 100644 index 0000000..0da8ded Binary files /dev/null and b/default-templates/img/gravatar-30.png differ diff --git a/default-templates/img/gravatar-31.png b/default-templates/img/gravatar-31.png new file mode 100644 index 0000000..84f371d Binary files /dev/null and b/default-templates/img/gravatar-31.png differ diff --git a/default-templates/img/noodles-default-image.png b/default-templates/img/noodles-default-image.png new file mode 100644 index 0000000..1a53105 Binary files /dev/null and b/default-templates/img/noodles-default-image.png differ diff --git a/default-templates/js/jquery.noodles.js b/default-templates/js/jquery.noodles.js new file mode 100644 index 0000000..3965367 --- /dev/null +++ b/default-templates/js/jquery.noodles.js @@ -0,0 +1,58 @@ +/* -- BEGIN LICENSE BLOCK ---------------------------------- + * This file is part of noodles, a plugin for Dotclear 2. + * + * Copyright (c) 2009 JC Denis and contributors + * jcdenis@gdwd.com + * + * Licensed under the GPL version 2.0 license. +* A copy of this license is available in LICENSE file or at + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * -- END LICENSE BLOCK ------------------------------------*/ + +;if(window.jQuery) (function($) { + + $.fn.noodles = function(options) { + + var opts = $.extend({}, $.fn.noodles.defaults, options); + + return this.each(function() { + parseNoodle(this,opts.service_url,opts.service_func,opts.imgPlace,opts.imgId); + }); + }; + + function parseNoodle(target,service_url,service_func,imgPlace,imgId) { + + var cur_line = $(target); + var content = encodeURIComponent($(target).get()); + + $.post(service_url,{noodleContent:content,noodleId:imgId}, + function(data){ + data=$(data); + if(data.find('rsp').attr('status')=='ok' && $(data).find('noodle').attr('src')) + { + var size = $(data).find('noodle').attr('size')+'px'; + var res = $(''); + $(res).addClass('noodles-'+imgId).height(size).width(size); + + if (imgPlace=='append') + $(cur_line).append($(res)); + if (imgPlace=='prepend') + $(cur_line).prepend($(res)); + if (imgPlace=='before') + $(cur_line).before($(res)); + if (imgPlace=='after') + $(cur_line).after($(res)); + } + } + ); + return target; + } + + $.fn.noodles.defaults = { + service_url: '', + service_func: 'getNoodle', + imgPlace: 'prepend', + imgId: '' + }; + +})(jQuery); diff --git a/icon.png b/icon.png new file mode 100644 index 0000000..ecafd2f Binary files /dev/null and b/icon.png differ diff --git a/inc/_default_noodles.php b/inc/_default_noodles.php new file mode 100644 index 0000000..fafb625 --- /dev/null +++ b/inc/_default_noodles.php @@ -0,0 +1,96 @@ +add('posts',__('Entries'),'',array('othersNoodles','publicPosts')); +$__default_noodles->posts->size = 48; +$__default_noodles->posts->css = 'float:right;margin:4px;'; + +# Comments (by public behavior) +$__default_noodles->add('comments',__('Comments'),'',array('othersNoodles','publicComments')); +$__default_noodles->comments->active = true; +$__default_noodles->comments->size = 48; +$__default_noodles->comments->css = 'float:left;margin:4px;'; + +# Block with post title link (like homepage posts) +$__default_noodles->add('titlesposts',__('Entries titles'),array('genericNoodles','postURL')); +$__default_noodles->titlesposts->target = '.post-title a'; +$__default_noodles->titlesposts->css = 'margin-right:2px;'; + +if ($core->plugins->moduleExists('widgets')) { + + # Widget Selected entries + $__default_noodles->add('bestof',__('Selected entries'),array('genericNoodles','postURL')); + $__default_noodles->bestof->target = '.selected li a'; + $__default_noodles->bestof->css = 'margin-right:2px;'; + + # Widget Last entries + $__default_noodles->add('lastposts',__('Last entries'),array('genericNoodles','postURL')); + $__default_noodles->lastposts->target = '.lastposts li a'; + $__default_noodles->lastposts->css = 'margin-right:2px;'; + + # Widget Last comments + $__default_noodles->add('lastcomments',__('Last comments'),array('widgetsNoodles','lastcomments')); + $__default_noodles->lastcomments->active = true; + $__default_noodles->lastcomments->target = '.lastcomments li a'; + $__default_noodles->lastcomments->css = 'margin-right:2px;'; +} + +# Plugin auhtorMode +if ($core->plugins->moduleExists('authorMode') + && $core->blog->settings->authormode->authormode_active) { + + $__default_noodles->add('authorswidget',__('Authors widget'),array('authormodeNoodles','authors')); + $__default_noodles->authorswidget->target = '#authors ul li a'; + $__default_noodles->authorswidget->css = 'margin-right:2px;'; + + $__default_noodles->add('author',__('Author'),'',array('authormodeNoodles','author')); + $__default_noodles->author->active = true; + $__default_noodles->author->size = 48; + $__default_noodles->author->target = '.dc-author #content-info h2'; + $__default_noodles->author->css = 'clear:left; float:left;margin-right:2px;'; + + $__default_noodles->add('authors',__('Authors'),array('authormodeNoodles','authors')); + $__default_noodles->authors->active = true; + $__default_noodles->authors->size = 32; + $__default_noodles->authors->target = '.dc-authors .author-info h2 a'; + $__default_noodles->authors->css = 'clear:left; float:left; margin:4px;'; +} + +# Plugin rateIt +if ($core->plugins->moduleExists('rateIt') + && $core->blog->settings->rateit->rateit_active) { + + $__default_noodles->add('rateitpostsrank',__('Top rated entries'),array('genericNoodles','postURL')); + $__default_noodles->rateitpostsrank->target = '.rateitpostsrank.rateittypepost ul li a'; // Only "post" type + $__default_noodles->rateitpostsrank->css = 'margin-right:2px;'; +} + +# Plugin lastpostsExtend +if ($core->plugins->moduleExists('lastpostsExtend')) { + + $__default_noodles->add('lastpostsextend',__('Last entries (extend)'),array('genericNoodles','postURL')); + $__default_noodles->lastpostsextend->target = '.lastpostsextend ul li a'; + $__default_noodles->lastpostsextend->css = 'margin-right:2px;'; +} + +# --BEHAVIOR-- initDefaultNoodles +$core->callBehavior('initDefaultNoodles',$__default_noodles); + +?> \ No newline at end of file diff --git a/inc/_noodles_functions.php b/inc/_noodles_functions.php new file mode 100644 index 0000000..8db492e --- /dev/null +++ b/inc/_noodles_functions.php @@ -0,0 +1,172 @@ +getPostTypes(); + $reg = '@^'.str_replace('%s','(.*?)', + preg_quote($core->blog->url.$types['post']['public_url'])).'$@'; + + $ok = preg_match($reg,$content,$m); + + if (!$ok || !$m[1]) return ''; + + $rs = $core->blog->getPosts( + array('no_content'=>1,'post_url'=>urldecode($m[1]),'limit'=>1) + ); + + if ($rs->isEmpty()) return ''; + + return $rs->user_email; + } +} + +# Miscellaneous +class othersNoodles +{ + public static function publicPosts($core,$noodle) + { + if (!$noodle->active) return; + + $bhv = $noodle->place == 'prepend' || $noodle->place == 'before' ? + 'publicEntryBeforeContent' : 'publicEntryAfterContent'; + + $core->addBehavior($bhv,array('othersNoodles','publicEntryContent')); + } + + public static function publicEntryContent() + { + global $core,$_ctx,$__noodles; + + $m = $_ctx->posts->getAuthorEmail(false); + $c = $__noodles->posts->css; + $s = $__noodles->posts->size; + $r = $__noodles->posts->rating; + $d = $core->blog->settings->noodles->noodles_image ? + urlencode(noodlesLibImagePath::getUrl($core,'noodles')) : ''; + + echo + ''; + } + + public static function publicComments($core,$noodle) + { + if (!$noodle->active) return; + + $bhv = $noodle->place == 'prepend' || $noodle->place == 'before' ? + 'publicCommentBeforeContent' : 'publicCommentAfterContent'; + + $core->addBehavior($bhv,array('othersNoodles','publicCommentContent')); + } + + public static function publicCommentContent() + { + global $core,$_ctx,$__noodles; + + $m = $_ctx->comments->getEmail(false); + $c = $__noodles->comments->css; + $s = $__noodles->comments->size; + $r = $__noodles->comments->rating; + $d = $core->blog->settings->noodles->noodles_image ? + urlencode(noodlesLibImagePath::getUrl($core,'noodles')) : ''; + + echo + ''; + } +} + +# Plugin Widgets +class widgetsNoodles +{ + public static function lastcomments($noodle,$content='') + { + global $core; + + $ok = preg_match('@\#c([0-9]+)$@',urldecode($content),$m); + + if (!$ok || !$m[1]) return ''; + + $rs = $core->blog->getComments( + array('no_content'=>1,'comment_id'=>$m[1],'limit'=>1) + ); + + if (!$rs->isEmpty()) return $rs->comment_email; + + return ''; + } +} + +# Plugin authorMode +class authormodeNoodles +{ + public static function authors($noodle,$content='') + { + global $core; + $ok = preg_match('@\/([^\/]*?)$@',$content,$m); + + if (!$ok || !$m[1]) return ''; + + $rs = $core->getUser($m[1]); + + if ($rs->isEmpty()) return ''; + + return $rs->user_email; + } + + public static function author($core,$noodle) + { + if ($noodle->active) + { + $core->addBehavior('publicHeadContent', + array('authormodeNoodles','publicHeadContent')); + } + } + + public static function publicHeadContent() + { + global $core,$_ctx,$__noodles; + + if ($_ctx->current_tpl != 'author.html') return; + + $id = $_ctx->users->user_id; + $u = $core->getUser($id); + $m = $u->user_email; + $c = $__noodles->author->css; + $s = $__noodles->author->size; + $r = $__noodles->author->rating; + $d = $core->blog->settings->noodles->noodles_image ? + urlencode(noodlesLibImagePath::getUrl($core,'noodles')) : ''; + + echo + '\n"; + } +} +?> \ No newline at end of file diff --git a/inc/class.noodles.php b/inc/class.noodles.php new file mode 100644 index 0000000..3838e08 --- /dev/null +++ b/inc/class.noodles.php @@ -0,0 +1,166 @@ +noodles[$id] = new noodle($id,$name,$js_callback,$php_callback); + } + + public function __get($id) + { + return isset($this->noodles[$id]) ? $this->noodles[$id] : null; + } + + public function __set($id,$noodle) + { + return $this->noodles[$id] = $noodle; + } + + public function exists($id) + { + return isset($this->noodles[$id]); + } + + public function isEmpty() + { + return !count($this->noodles); + } + + public function noodles() + { + return $this->noodles; + } +} + +class noodle +{ + private $id; + private $name; + private $js_callback; + private $php_callback; + private $settings = array( + 'active' => 0, + 'rating' => 'g', + 'size' => 16, + 'target' => '', + 'place' => 'prepend' + ); + + public function __construct($id,$name,$js_callback,$php_callback=null) + { + $this->id = $id; + $this->name = $name; + $this->js_callback = $js_callback; + $this->php_callback = $php_callback; + } + + public function id() + { + return $this->id; + } + + public function name() + { + return $this->name; + } + + public function jsCallback($g,$content='') + { + if (!is_callable($this->js_callback)) return null; + return call_user_func($this->js_callback,$g,$content); + } + + public function hasJsCallback() + { + return !empty($this->js_callback); + } + + public function phpCallback($core) + { + if (!is_callable($this->php_callback)) return null; + return call_user_func($this->php_callback,$core,$this); + } + + public function hasPhpCallback() + { + return !empty($this->php_callback); + } + + public function set($type,$value) + { + switch ($type) + { + case 'active': + $this->settings['active'] = abs((integer) $value); + break; + + case 'rating': + $this->settings['rating'] = in_array($value,array('g','pg','r','x')) ? + $value : 'g'; + break; + + case 'size': + $this->settings['size'] = + in_array($value,array(16,24,32,48,56,64,92,128,256)) ? + $value : 16; + break; + + case 'css': + $this->settings['css'] = (string) $value; + break; + + case 'target': + $this->settings['target'] = (string) $value; + break; + + case 'place': + $this->settings['place'] = + in_array($value,array('append','prepend','before','after')) ? + $value : 'prepend'; + break; + } + } + + public function __set($type,$value) + { + $this->set($type,$value); + } + + public function get($type) + { + return isset($this->settings[$type]) ? $this->settings[$type] : null; + } + + public function __get($type) + { + return $this->get($type); + } +} +?> \ No newline at end of file diff --git a/inc/lib.image.path.php b/inc/lib.image.path.php new file mode 100644 index 0000000..615a736 --- /dev/null +++ b/inc/lib.image.path.php @@ -0,0 +1,74 @@ +plugins->moduleExists($m) + || !$core->url->getBase($m.'module')) { + return array( + 'theme'=>array('dir'=>null,'url'=>null), + 'public'=>array('dir'=>null,'url'=>null), + 'module'=>array('dir'=>null,'url'=>null), + ); + } + + return array( + 'theme' => array( + 'dir' => $core->blog->themes_path.'/'.$core->blog->settings->system->theme.'/img/'.$m.'-default-image.png', + 'url' => $core->blog->settings->system->themes_url.$core->blog->settings->system->theme.'/img/'.$m.'-default-image.png' + ), + 'public' => array( + 'dir' => $core->blog->public_path.'/'.$m.'-default-image.png', + 'url' => $core->blog->host.path::clean($core->blog->settings->system->public_url).'/'.$m.'-default-image.png' + ), + 'module' => array( + 'dir' => $core->plugins->moduleRoot($m).'/default-templates/img/'.$m.'-default-image.png', + 'url' => $core->blog->url.$core->url->getBase($m.'module').'/img/'.$m.'-default-image.png' + ) + ); + } + + public static function getUrl($core,$m='') + { + $files = self::getArray($core,$m); + foreach($files as $k => $file) { + if (file_exists($files[$k]['dir'])) + return $files[$k]['url']; + } + return null; + } + + public static function getPath($core,$m='') + { + $files = self::getArray($core,$m); + foreach($files as $k => $file) { + if (file_exists($files[$k]['dir'])) + return $files[$k]['dir']; + } + return null; + } + + public static function getSize($core,$m='') + { + if (!($img = self::getPath($core,$m))) + return array('w'=>16,'h'=>16); + else { + $info = getimagesize($img); + return array('w'=>$info[0],'h'=>floor($info[1] /3)); + } + } +} +?> \ No newline at end of file diff --git a/index.php b/index.php new file mode 100644 index 0000000..a54fe56 --- /dev/null +++ b/index.php @@ -0,0 +1,339 @@ +blog->settings->noodles; +$msg = isset($_POST['done']) ? __('Configuration successfully updated') : ''; +$tab = isset($_REQUEST['tab']) ? $_REQUEST['tab'] : 'blocs'; +$img_green = '%s'; +$img_red = '%s'; + +include dirname(__FILE__).'/inc/_default_noodles.php'; + +$__noodles = noodles::decode($s->noodles_object); + +if ($__noodles->isEmpty()) +{ + $__noodles = $__default_noodles; +} +else +{ + $default_noodles_array = $__default_noodles->noodles(); + foreach($default_noodles_array AS $id => $noodle) + { + if ($__noodles->exists($id)) continue; + $__noodles->{$id} = $noodle; + } +} + +if (!$s->noodles_active) +{ + $tab = 'settings'; +} + +$default_avatars_images = files::scandir(dirname(__FILE__).'/default-templates/img/'); +$avatar_paths = noodlesLibImagePath::getArray($core,'noodles'); + +$combo_active = array( + __('no') => 0, + __('yes') => 1 +); +$combo_place = array( + __('Begin') => 'prepend', + __('End') => 'append', + __('Before') => 'before', + __('After') => 'after' +); +$combo_rating = array( + 'G'=>'g', + 'PG'=>'pg', + 'R'=>'r', + 'X'=>'x' +); +$combo_size = array( + '16px'=>16, + '24px'=>24, + '32px'=>32, + '48px'=>48, + '56px'=>56, + '64px'=>64, + '92px'=>92, + '128px'=>128, + '256px'=>256 +); + +if (!empty($_POST['save']) && $tab == 'settings') +{ + try + { + $s->put('noodles_active',$_POST['noodles_active'],'boolean'); + + # Destination image according to noodlesLibImagePath() + $dest_file = DC_ROOT.'/'.$s->public_path.'/noodles-default-image.png'; + + # user upload image + if ($_POST['noodles_image'] == 'user') + { + if (2 == $_FILES['noodlesuserfile']['error']) + { + throw new Exception(__('Maximum file size exceeded')); + } + if ($_FILES['noodlesuserfile']['type'] != 'image/x-png') + { + throw new Exception(__('Image must be in png format')); + } + if (0 != $_FILES['noodlesuserfile']['error']) + { + throw new Exception(__('Something went wrong while download file')); + } + if ($_FILES['noodlesuserfile']['type'] != 'image/x-png') + { + throw new Exception(__('Image must be in png format')); + } + if (move_uploaded_file($_FILES['noodlesuserfile']['tmp_name'],$dest_file)) + { + $s->put('noodles_image',1,'boolean'); + } + } + # Default gravatar.com avatar + elseif ($_POST['noodles_image'] == 'gravatar.com') + { + $s->put('noodles_image',0,'boolean'); + } + # existsing noodles image on blog + elseif ($_POST['noodles_image'] == 'existsing') + { + $s->put('noodles_image',1,'boolean'); + } + # noodles image + elseif (preg_match('/^gravatar-[0-9]+.png$/',$_POST['noodles_image'])) + { + $source = dirname(__FILE__).'/default-templates/img/'.$_POST['noodles_image']; + + if (!file_exists($source)) + { + throw new Exception(__('Something went wrong while search file')); + } + if (file_put_contents($dest_file,file_get_contents($source))) + { + $s->put('noodles_image',1,'boolean'); + } + } + + $core->blog->triggerBlog(); + http::redirect('plugin.php?p=noodles&tab=settings&done=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +if (!empty($_POST['save']) && $tab == 'blocs' && !empty($_POST['noodle'])) +{ + try + { + foreach($_POST['noodle'] as $id => $bloc) + { + foreach($bloc as $k => $v) + { + $__noodles->{$id}->set($k,$v); + } + } + $s->put('noodles_object',$__noodles->encode(),'string'); + + $core->blog->triggerBlog(); + http::redirect('plugin.php?p=noodles&tab=blocs&done=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +if (!empty($_POST['reset']) && $tab == 'blocs') +{ + try + { + $s->put('noodles_object','','string'); + $core->blog->triggerBlog(); + http::redirect('plugin.php?p=noodles&tab=blocs&done=1'); + } + catch (Exception $e) + { + $core->error->add($e->getMessage()); + } +} + +echo +''. +''. +''.__('Noodles').''. +dcPage::jsLoad('js/_posts_list.js'). +dcPage::jsPageTabs($tab). +''. +''. +'

'.html::escapeHTML($core->blog->name).' › '.__('Noodles').'

'. + (!empty($msg) ? '

'.$msg.'

' : ''); + +# Blocs +if ($s->noodles_active) +{ + echo + '
'. + '
'. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''; + + foreach($__noodles->noodles() as $noodle) + { + echo + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''; + } + echo + '
'.__('Name').''.__('Enable').''.__('Size').''.__('Rating').''.__('PHP').''.__('JS').''.__('JS target').''.__('JS place').''.__('Adjust avatar CSS').'
'.$noodle->name().''.form::combo(array('noodle['.$noodle->id().'][active]'),$combo_active,$noodle->active).''.form::combo(array('noodle['.$noodle->id().'][size]'),$combo_size,$noodle->size).''.form::combo(array('noodle['.$noodle->id().'][rating]'),$combo_rating,$noodle->rating).''.($noodle->hasPhpCallback() ? $img_green : $img_red).''.$img_green.''.form::field(array('noodle['.$noodle->id().'][target]'),20,255,$noodle->target).''.form::combo(array('noodle['.$noodle->id().'][place]'),$combo_place,$noodle->place).''. + form::textArea(array('noodle['.$noodle->id().'][css]'),50,2,$noodle->css). + ' .noodles-'.$noodle->id().'{}
'. + '

'. + form::hidden(array('p'),'noodles'). + form::hidden(array('tab'),'blocs'). + $core->formNonce(). + ' '. + '

'. + '
'. + '
'; +} + +# Settings +echo +'
'. +'
'. +'
'.__('Options').''. +'

'. + +'
'. +'
'.__('Default avatar').''. +''. +''; + +// By default use gravatar.com image +$default = '' == $s->noodles_image; + +echo +''. +''. +''; + +if (!$default) +{ + $exists = false; + + // then use theme image + if (file_exists($avatar_paths['theme']['dir'])) + { + $exists = $avatar_paths['theme']; + } + // then public image + elseif (file_exists($avatar_paths['public']['dir'])) + { + $exists = $avatar_paths['public']; + } + // then module + elseif (file_exists($avatar_paths['module']['dir'])) + { + $exists = $avatar_paths['module']; + } + if ($exists) + { + $sz = getimagesize($exists['dir']); + $sz[2] = files::size(filesize($exists['dir'])); + + echo + ''. + ''. + ''. + ''. + ''; + } +} + +// noodles avatars +sort($default_avatars_images); +foreach($default_avatars_images AS $f) +{ + if (!preg_match('/gravatar-[0-9]+.png/',$f)) continue; + $sz = getimagesize(dirname(__FILE__).'/default-templates/img/'.$f); + $sz[2] = files::size(filesize(dirname(__FILE__).'/default-templates/img/'.$f)); + + echo + ''. + ''. + ''. + ''. + ''; +} + +// user upload avatar +echo +''. +''. +''. +''. +'
 '.__('Avatar').''.__('size').'
'.$sz[0].'x'.$sz[1].'
'.$sz[2].'
'.$sz[0].'x'.$sz[1].'
'.$sz[2].'
'.form::radio(array('noodles_image'),'user').''.form::hidden(array('MAX_FILE_SIZE'),30000). + ' *
'. +'

* '.__('Image must be in "png" format and have a maximum file size of 30Ko').'

'. +'
'. +'

'. +form::hidden(array('p'),'noodles'). +form::hidden(array('tab'),'settings'). +$core->formNonce(). +'

'. +'
'. +'
'; + +# Footer +echo +'
+

+noodles - '.$core->plugins->moduleInfo('noodles','version').'  +'.__('Noodles').' +

+'; +?> \ 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..bfc152a --- /dev/null +++ b/locales/fr/main.lang.php @@ -0,0 +1,83 @@ + \ No newline at end of file diff --git a/locales/fr/main.po b/locales/fr/main.po new file mode 100644 index 0000000..ef24cec --- /dev/null +++ b/locales/fr/main.po @@ -0,0 +1,117 @@ +# Language: Français +# Module: noodles - 0.6 +# Date: 2010-06-22 15:54:18 +# Translated with translater 1.4 + +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: noodles 0.6\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2010-06-22T15:54:18+00:00\n" +"Last-Translator: JC Denis\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" + +#: inc/_default_noodles.php:32 +msgid "Entries titles" +msgstr "Titres des billets" + +#: inc/_default_noodles.php:59 +msgid "Authors widget" +msgstr "Widgets des auteurs" + +#: index.php:54 +msgid "Begin" +msgstr "Début" + +#: index.php:55 +msgid "End" +msgstr "Fin" + +#: index.php:56 +msgid "Before" +msgstr "Avant" + +#: index.php:57 +msgid "After" +msgstr "Après" + +#: index.php:91 +msgid "Maximum file size exceeded" +msgstr "Taille maximum de fichier dépassée" + +#: index.php:95 +#: index.php:103 +msgid "Image must be in png format" +msgstr "L'image doit être au format png" + +#: index.php:99 +msgid "Something went wrong while download file" +msgstr "Une erreur est survenue lors du téléchargement de l'image" + +#: index.php:127 +msgid "Something went wrong while search file" +msgstr "Une erreur est survenue pendant la recherche de fichier" + +#: index.php:195 +msgid "Controls" +msgstr "Contrôles" + +#: index.php:198 +msgid "Name" +msgstr "Nom" + +#: index.php:199 +msgid "Enable" +msgstr "Activer" + +#: index.php:200 +msgid "Size" +msgstr "Taille" + +#: index.php:201 +msgid "Rating" +msgstr "Évaluation" + +#: index.php:204 +msgid "JS target" +msgstr "Cible JS" + +#: index.php:205 +msgid "JS place" +msgstr "Emplacement JS" + +#: index.php:206 +msgid "Adjust avatar CSS" +msgstr "Ajuster la CSS de l'image" + +#: index.php:233 +msgid "Reset" +msgstr "RAZ" + +#: index.php:240 +msgid "Settings" +msgstr "Paramètres" + +#: index.php:245 +msgid "Enable plugin" +msgstr "Activer l'extension" + +#: index.php:248 +msgid "Default avatar" +msgstr "Avatar par défaut" + +#: index.php:249 +msgid "size" +msgstr "taille" + +#: index.php:258 +msgid "gravatar.com default image" +msgstr "Image par défaut de gravatar.com" + +#: index.php:321 +msgid "Image must be in \"png\" format and have a maximum file size of 30Ko" +msgstr "L'image doit être au format \"png\" et avoir une taille maximum de 30Ko" + diff --git a/release.txt b/release.txt new file mode 100644 index 0000000..50b2376 --- /dev/null +++ b/release.txt @@ -0,0 +1,14 @@ +0.6.1 20100705 + * Fixed lowercase email (tks Damien Clauzel) + * Fixed a stupid error on admin page + +0.6 20100605 + * Switched to DC 2.2 + * Fixed javascript encode URI + * Fixed image paths and urls + +0.5 20090923 + * Fixed DC 2.1.6 URL handlers ending + * Fixed image size in js + * Removed ''url prefix'' settings as myUrlHandlers does it perfectly + * Added _uninstall.php feature \ No newline at end of file