# HG changeset patch # User Dan # Date 1192931486 14400 # Node ID eec079676fe77b8d5a6e90de63cc49986ceea58e # Parent bf0fdec102e9072d2cf661231e341dcbf238e441# Parent db8a849ad4c9310d652cd62098eaffe6d5a2ce16 Merging in changes from db8a849ad4c9 diff -r db8a849ad4c9 -r eec079676fe7 ajax.php --- a/ajax.php Sat Oct 06 20:36:52 2007 -0400 +++ b/ajax.php Sat Oct 20 21:51:26 2007 -0400 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.1.1 + * Version 1.0.2 (Coblynau) * Copyright (C) 2006-2007 Dan Fuhry * * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License @@ -33,35 +33,50 @@ define('ENANO_ROOT', dirname($filename)); require(ENANO_ROOT.'/includes/functions.php'); require(ENANO_ROOT.'/includes/dbal.php'); + require(ENANO_ROOT.'/includes/json.php'); $db = new mysql(); $db->connect(); - // should be connected now + // result is sent using JSON + $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); + $return = Array( + 'mode' => 'success', + 'users_real' => Array() + ); + + // should be connected to the DB now $name = (isset($_GET['name'])) ? $db->escape($_GET['name']) : false; if ( !$name ) { - die('userlist = new Array(); errorstring=\'Invalid URI\''); + $return = array( + 'mode' => 'error', + 'error' => 'Invalid URI' + ); + die( $json->encode($return) ); } - $q = $db->sql_query('SELECT username,user_id FROM '.table_prefix.'users WHERE lcase(username) LIKE lcase(\'%'.$name.'%\');'); + $allowanon = ( isset($_GET['allowanon']) && $_GET['allowanon'] == '1' ) ? '' : ' AND user_id > 1'; + $q = $db->sql_query('SELECT username FROM '.table_prefix.'users WHERE lcase(username) LIKE lcase(\'%'.$name.'%\')' . $allowanon . ' ORDER BY username ASC;'); if ( !$q ) { - die('userlist = new Array(); errorstring=\'MySQL error selecting username data: '.addslashes(mysql_error()).'\''); + $return = array( + 'mode' => 'error', + 'error' => 'MySQL error selecting username data: '.addslashes(mysql_error()) + ); + die( $json->encode($return) ); } - if($db->numrows() < 1) - { - die('userlist = new Array(); errorstring=\'No usernames found\';'); - } - echo 'var errorstring = false; userlist = new Array();'; $i = 0; while($r = $db->fetchrow()) { - echo "userlist[$i] = '".addslashes($r['username'])."'; "; + $return['users_real'][] = $r['username']; $i++; } $db->free_result(); // all done! :-) $db->close(); + + echo $json->encode( $return ); + exit; } @@ -101,7 +116,7 @@ } else { - echo 'Error saving the page: '.$e; + echo '
Error saving the page: '.$e.'
'; } break; case "protect": diff -r db8a849ad4c9 -r eec079676fe7 cron.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cron.php Sat Oct 20 21:51:26 2007 -0400 @@ -0,0 +1,54 @@ + $tasks ) +{ + $last_run_threshold = time() - ( $interval * 3600 ); + if ( $last_run_threshold >= $last_run ) + { + foreach ( $tasks as $task ) + { + @call_user_func($task); + } + } +} + +header('Pragma: no-cache'); +header('Cache-control: no-cache'); +header('Expires: Thu, 1 Jan 1970 00:00:01 GMT'); +header('Content-type: image/gif'); + +echo ENANO_GIF_SPACER; + +?> diff -r db8a849ad4c9 -r eec079676fe7 includes/clientside/sbedit.js --- a/includes/clientside/sbedit.js Sat Oct 06 20:36:52 2007 -0400 +++ b/includes/clientside/sbedit.js Sat Oct 20 21:51:26 2007 -0400 @@ -123,3 +123,71 @@ }); } +function ajaxRenameSidebarStage1(parent, id) +{ + var oldname = parent.firstChild.nodeValue; + parent.removeChild(parent.firstChild); + parent.ondblclick = function() {}; + parent._idcache = id; + var input = document.createElement('input'); + input.type = 'text'; + input.sbedit_id = id; + input.oldvalue = oldname; + input.onkeyup = function(e) + { + if ( typeof(e) != 'object' ) + return false; + if ( !e.keyCode ) + return false; + if ( e.keyCode == 13 ) + { + ajaxRenameSidebarStage2(this); + } + if ( e.keyCode == 27 ) + { + ajaxRenameSidebarCancel(this); + } + }; + input.onblur = function() + { + ajaxRenameSidebarCancel(this); + }; + input.value = oldname; + input.style.fontSize = '7pt'; + parent.appendChild(input); + input.focus(); +} + +function ajaxRenameSidebarStage2(input) +{ + var newname = input.value; + var id = input.sbedit_id; + var parent = input.parentNode; + parent.removeChild(input); + parent.appendChild(document.createTextNode(newname)); + parent.ondblclick = function() { ajaxRenameSidebarStage1(this, this._idcache); return false; }; + var img = document.createElement('img'); + img.src = scriptPath + '/images/loading.gif'; + parent.appendChild(img); + newname = ajaxEscape(newname); + ajaxPost(makeUrlNS('Special', 'EditSidebar', 'ajax&noheaders&action=rename&id='+id), 'newname=' +newname, function() + { + if ( ajax.readyState == 4 ) + { + parent.removeChild(img); + if ( ajax.responseText != 'GOOD' ) + new messagebox(MB_OK|MB_ICONSTOP, 'Error renaming block', ajax.responseText); + } + }); +} + +function ajaxRenameSidebarCancel(input) +{ + var newname = input.oldvalue; + var id = input.sbedit_id; + var parent = input.parentNode; + parent.removeChild(input); + parent.appendChild(document.createTextNode(newname)); + parent.ondblclick = function() { ajaxRenameSidebarStage1(this, this._idcache); return false; }; +} + diff -r db8a849ad4c9 -r eec079676fe7 includes/clientside/static/SpryEffects.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/static/SpryEffects.js Sat Oct 20 21:51:26 2007 -0400 @@ -0,0 +1,29 @@ +// Spry.Effect.js - version 0.38 - Spry Pre-Release 1.6 +// +// Copyright (c) 2007. Adobe Systems Incorporated. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Adobe Systems Incorporated nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('h b;j(!b)b={};b.15=1;b.1J=2;j(!b.c)b.c={};b.c.4Z={43:p(19,1c,1e,r){j(19>r)q 1e+1c;q 1c+(19/r)*1e},4q:p(19,1c,1e,r){j(19>r)q 1e+1c;q 1c+((-1g.5W((19/r)*1g.5V)/2)+0.5)*1e},6a:p(19,1c,1e,r){j(19>r)q 1e+1c;q 1c+1g.4C(19/r,2)*1e},7G:p(19,1c,1e,r){j(19>r)q 1e+1c;q 1c+1g.50(19/r)*1e},3I:p(19,1c,1e,r){j(19>r)q 1e+1c;q 1c+1g.50((-1g.5W((19/r)*1g.5V)/2)+0.5)*1e},5Z:p(19,1c,1e,r){j(19>r)q 1e+1c;h 1F=19/r;q 1c+1g.50(1-1g.4C((1F-1),2))*1e},7J:p(19,1c,1e,r){j(19>r)q 1e+1c;q 1c+(0.5+1g.7E(17*19/r)/2)*1e},7D:p(19,1c,1e,r){j(19>r)q 1e+1c;h 1F=19/r;q 1c+(5*1g.4C(1F,3)-6.4*1g.4C(1F,2)+2*1F)*1e}};18(h 51 3K b.c.4Z){b[51]=b.c.4Z[51]}b.c.3V=p(){8.2R=[]};b.c.3V.w.4W=p(k,d){h a={};a.k=b.c.1x(k);a.d=d;18(h i=0;i<8.2R.M;i++)j(8.5U(8.2R[i],a))q 8.2R[i].J;q D};b.c.3V.w.6e=p(J,k,d){j(!8.4W(k,d)){h 2C=8.2R.M;8.2R[2C]={};h 4F=8.2R[2C];4F.J=J;4F.k=b.c.1x(k);4F.d=d}};b.c.3V.w.5U=p(3U,32){j(3U.k!=32.k)q D;h 52=b.c.m.6b(3U.d,32.d);j(52){j(1n 32.d.3A==\'p\')3U.d.3A=32.d.3A;j(1n 32.d.3o==\'p\')3U.d.3o=32.d.3o}q 52};h 4R=B b.c.3V;j(!b.c.m)b.c.m={};b.c.m.1D=p(61){7V(\'b.c 7W: \'+61)};b.c.m.21=p(J){b.c.m.1D(\'7S \'+J+\' 7R 7N\\\'t 7M 7w 7P a 5o p 7Q. \'+"\\n"+\'7Y 7r b 7c 7f 7e.\');q D};b.c.m.1G=p(){8.x=0;8.y=0;8.N="1Q"};b.c.m.2d=p(){8.A=0;8.C=0;8.N="1Q"};b.c.m.3m=p(5R){h 1H=5R.7h(16);j(1H.M==1)1H="0"+1H;q 1H};b.c.m.2e=p(64){q Y(64,16)};b.c.m.3j=p(5Q,5J,5I){h 3m=b.c.m.3m;h 5L=3m(5Q);h 5O=3m(5J);h 5N=3m(5I);4i=5L.7a(5O,5N).6i();4i=\'#\'+4i;q 4i};b.c.m.5k=p(2K){j(2K.7j(/^#[0-7s-f]{3}$/i)){h 3x=2K.6l(\'\');h 2K=\'#\';18(h i=1;i<3x.M;i++){2K+=3x[i]+\'\'+3x[i]}}q 2K};b.c.m.5f=p(4k){j(4k.25(\'-\')==-1){q 4k}h 44=4k.6l(\'-\');h 53=O;h 4y=\'\';18(h i=0;i<44.M;i++){j(44[i].M>0){j(53){4y=44[i];53=D}H{h s=44[i];4y+=s.7q(0).6i()+s.2s(1)}}}q 4y};b.c.m.1N=p(1i){h 1H=D;j(1n 1i==\'58\'&&1i.M>0&&1i.33("%")>0)1H=O;q 1H};b.c.m.1k=p(1i){h 1H=0;38{1H=4a(1i.2s(0,1i.33("%")))}37(e){b.c.m.1D(\'b.c.m.1k: \'+e)}q 1H};b.c.m.2A=p(1i){h 1H=0;j(1n 1i==\'5T\')q 1i;h 4j=1i.33("1Q");j(4j==-1)4j=1i.M;38{1H=Y(1i.2s(0,4j),10)}37(e){}q 1H};b.c.m.6r=p(2X){j(2X){h 3e=2X.7l;71(3e){j(3e.5b==1)q 3e;3e=3e.7k}}q z};b.c.m.6A=p(3L,4Y){j(!3L||3L.5b!=1||!4Y)q;j(3L.7m()){h 2g=3L.7Z(\'7n\');h 6h=2g.M;18(h i=0;i<6h;i++){h 4X=2g[i];h 4T=b.c.4b(4X);4Y.7O([4X,4T.A,4T.C])}}};b.c.m.6b=p(35,3p){j(35==z&&3p==z)q O;j(35!=z&&3p!=z){h 4S=0;h 4U=0;18(h 8x 3K 35)4S++;18(h 8y 3K 3p)4U++;j(4S!=4U)q D;18(h 1y 3K 35){h 4V=1n 35[1y];h 6f=1n 3p[1y];j(4V!=6f||(4V!=\'3D\'&&35[1y]!=3p[1y]))q D}q O}q D};b.c.m.23=p(54,k,d){j(!d)h d={};d.1t=54;h 40=4R.4W(k,d);j(!40){40=B b.c[54](k,d);4R.6e(40,k,d)}40.2J();q O};j(!b.m)b.m={};b.m.2y=p(){8.2m=[];8.3Y=0};b.m.2y.w.2N=p(36){j(!36)q;h 2C=8.2m.M;18(h i=0;i<2C;i++)j(8.2m[i]==36)q;8.2m[2C]=36};b.m.2y.w.8n=p(36){j(!36)q;18(h i=0;i<8.2m.M;i++){j(8.2m[i]==36){8.2m.88(i,1);3P}}};b.m.2y.w.2t=p(3X,55){j(!3X)q;j(!8.3Y){h 2C=8.2m.M;18(h i=0;i<2C;i++){h 3y=8.2m[i];j(3y){j(1n 3y=="p")3y(3X,8,55);H j(3y[3X])3y[3X](8,55)}}}};b.m.2y.w.69=p(){j(--8.3Y<0){8.3Y=0;b.c.m.1D("82 69() 1s!\\n")}};b.m.2y.w.84=p(){++8.3Y};b.c.1x=p(2Q){h k=2Q;j(1n 2Q=="58")k=3f.70(2Q);j(k==z)b.c.m.1D(\'8c "\'+2Q+\'" 8j 4p.\');q k};b.c.1a=p(k,1y){h 1i;h 5e=b.c.m.5f(1y);38{j(k.11)1i=k.11[5e];j(!1i){j(3f.4J&&3f.4J.2x){h 5d=3f.4J.2x(k,z);1i=5d?5d.8m(1y):z}H j(k.57){1i=k.57[5e]}}}37(e){b.c.m.1D(\'b.c.1a: \'+e)}q 1i==\'8d\'?z:1i};b.c.1h=p(k,1y,1i){38{k.11[b.c.m.5f(1y)]=1i}37(e){b.c.m.1D(\'b.c.1h: \'+e)}};b.c.2Z=p(k,1y,3i){h 1z=3i?3i:k;h 3k=b.c.1a(1z,\'1R\');h 4E=b.c.1a(1z,\'2l\');j(3k==\'1Z\'){b.c.1h(1z,\'2l\',\'3d\');b.c.1h(1z,\'1R\',\'3T\');j(47.56)1z.5M()}h 6q=b.c.1a(k,1y);j(3k==\'1Z\'){b.c.1h(1z,\'1R\',\'1Z\');b.c.1h(1z,\'2l\',4E)}q 6q};b.c.2L=p(k){h 1F=b.c.1a(k,\'1L\');j(!1F||1F==\'5o\'){k.11.1L=\'6g\';j(47.56){k.11.1b=0;k.11.1f=0}}};b.c.5i=p(k){h 3E=b.c.1a(k,\'1R\');j(3E&&3E.3C()==\'1Z\')q O;h 3B=b.c.1a(k,\'2l\');j(3B&&3B.3C()==\'3d\')q O;q D};b.c.2o=p(k){h 3E=b.c.1a(k,\'1R\');j(3E&&3E.3C()==\'1Z\')b.c.1h(k,\'1R\',\'3T\');h 3B=b.c.1a(k,\'2l\');j(3B&&3B.3C()==\'3d\')b.c.1h(k,\'2l\',\'8h\')};b.c.3l=p(k){h 3z=b.c.1a(k,\'3z\');j(!3z||(3z.3C()!=\'3d\'&&3z.3C()!=\'81\')){h 5c=0;h 5g=/2M 7.0/.1j(27.26)&&/5n 5D/.1j(27.26);j(5g)5c=b.c.2n(k).C;b.c.1h(k,\'3z\',\'3d\');j(5g)b.c.1h(k,\'C\',5c+\'1Q\')}};b.c.65=p(k){h 6j=k.6t.M;18(h i=6j-1;i>=0;i--){h 2X=k.6t[i];j(2X.5b==3&&!/\\S/.1j(2X.8I))38{k.8z(2X)}37(e){b.c.m.1D(\'b.c.65: \'+e)}}};b.c.2x=p(k){q/2M/.1j(27.26)?k.57:3f.4J.2x(k,z)};b.c.4b=p(k){h 1T=B b.c.m.2d;h 1d=z;j(k.11.A&&/1Q/i.1j(k.11.A))1T.A=Y(k.11.A,10);H{1d=b.c.2x(k);h 1W=1d&&1d.A&&/1Q/i.1j(1d.A);j(1W)1T.A=Y(1d.A,10);j(!1W||1T.A==0)1T.A=k.8p}j(k.11.C&&/1Q/i.1j(k.11.C))1T.C=Y(k.11.C,10);H{j(!1d)1d=b.c.2x(k);h 1W=1d&&1d.C&&/1Q/i.1j(1d.C);j(1W)1T.C=Y(1d.C,10);j(!1W||1T.C==0)1T.C=k.8t}q 1T};b.c.2n=p(k,3i){h 1z=3i?3i:k;h 3k=b.c.1a(1z,\'1R\');h 4E=b.c.1a(1z,\'2l\');j(3k==\'1Z\'){b.c.1h(1z,\'2l\',\'3d\');b.c.1h(1z,\'1R\',\'3T\');j(47.56)1z.5M()}h 1T=b.c.4b(k);j(3k==\'1Z\'){b.c.1h(1z,\'1R\',\'1Z\');b.c.1h(1z,\'2l\',4E)}q 1T};b.c.5w=p(k){h o=b.c.1a(k,"1E");j(1n o==\'3D\'||o==z)o=1.0;q o};b.c.4G=p(2Q){q b.c.1a(2Q,"4e-2K")};b.c.3W=p(e,1y){h i=Y(b.c.1a(e,1y),10);j(5F(i))q 0;q i};b.c.48=p(k){h 1L=B b.c.m.1G;h 1d=z;j(k.11.1f&&/1Q/i.1j(k.11.1f))1L.x=Y(k.11.1f,10);H{1d=b.c.2x(k);h 1W=1d&&1d.1f&&/1Q/i.1j(1d.1f);j(1W)1L.x=Y(1d.1f,10);j(!1W||1L.x==0)1L.x=k.8g}j(k.11.1b&&/1Q/i.1j(k.11.1b))1L.y=Y(k.11.1b,10);H{j(!1d)1d=b.c.2x(k);h 1W=1d&&1d.1b&&/1Q/i.1j(1d.1b);j(1W)1L.y=Y(1d.1b,10);j(!1W||1L.y==0)1L.y=k.8a}q 1L};b.c.87=b.c.48;b.c.X=p(d){b.m.2y.1s(8);8.1t=\'X\';8.k=z;8.2D=0;8.8E=\'1Z\';8.1u=D;8.49=z;8.2f=0;j(!d)h d={};j(d.F)8.E=D;H 8.E=b.15;h 1q=8;j(d.3A!=z)8.2N({3Q:p(){38{1q.d.3A(1q.k,1q)}37(e){b.c.m.1D(\'b.c.X.w.2J: 3A 5Y: \'+e)}}});j(d.3o!=z)8.2N({3J:p(){38{1q.d.3o(1q.k,1q)}37(e){b.c.m.1D(\'b.c.X.w.29: 3o 5Y: \'+e)}}});8.d={r:1O,F:D,u:b.43,3c:16};8.5X(d);j(d.u)8.59(d.u);j(d.v)8.5a(d.v)};b.c.X.w=B b.m.2y();b.c.X.w.1v=b.m.X;b.c.X.w.1Y=O;b.c.X.w.5X=p(d){j(!d)q;18(h 1y 3K d)8.d[1y]=d[1y]};b.c.X.w.59=p(u){j(1n u==\'5T\'||u=="1"||u=="2")7d(Y(u,10)){5S 1:u=b.43;3P;5S 2:u=b.4q;3P;7g:b.c.m.1D(\'4Q u\')}H j(1n u==\'58\'){j(1n 47[u]==\'p\')u=47[u];H j(1n b[u]==\'p\')u=b[u];H b.c.m.1D(\'4Q u\')}8.d.u=u;j(1n 8.G!=\'3D\'){h l=8.G.M;18(h i=0;i' + ajax.responseText + ''); + return false; + } + + response = parseJSON(response); + var errorstring = false; + if ( response.mode == 'error' ) + { + errorstring = response.error; + } + else + { + var userlist = response.users_real; + } + if(errorstring) { html = ''+errorstring+''; diff -r db8a849ad4c9 -r eec079676fe7 includes/clientside/static/autofill.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/static/autofill.js Sat Oct 20 21:51:26 2007 -0400 @@ -0,0 +1,512 @@ +/** + * Javascript auto-completion for form fields. + */ + +var af_current = false; + +function AutofillUsername(parent, event, allowanon) +{ + // if this is IE, use the old code + if ( IE ) + { + ajaxUserNameComplete(parent); + return false; + } + if ( parent.afobj ) + { + parent.afobj.go(); + return true; + } + + parent.autocomplete = 'off'; + parent.setAttribute('autocomplete', 'off'); + + this.repeat = false; + this.event = event; + this.box_id = false; + this.boxes = new Array(); + this.state = false; + this.allowanon = ( allowanon ) ? true : false; + + if ( !parent.id ) + parent.id = 'afuser_' + Math.floor(Math.random() * 1000000); + + this.field_id = parent.id; + + // constants + this.KEY_UP = 38; + this.KEY_DOWN = 40; + this.KEY_ESC = 27; + this.KEY_TAB = 9; + this.KEY_ENTER = 13; + + // response cache + this.responses = new Object(); + + // ajax placeholder + this.process_dataset = function(resp_json) + { + // window.console.info('Processing the following dataset.'); + // window.console.debug(resp_json); + var autofill = this; + + if ( typeof(autofill.event) == 'object' ) + { + if ( autofill.event.keyCode ) + { + if ( autofill.event.keyCode == autofill.KEY_ENTER && autofill.boxes.length < 1 && !autofill.box_id ) + { + // user hit enter after accepting a suggestion - submit the form + var frm = findParentForm($(autofill.field_id).object); + frm._af_acting = false; + frm.submit(); + // window.console.info('Submitting form'); + return false; + } + if ( autofill.event.keyCode == autofill.KEY_UP || autofill.event.keyCode == autofill.KEY_DOWN || autofill.event.keyCode == autofill.KEY_ESC || autofill.event.keyCode == autofill.KEY_TAB || autofill.event.keyCode == autofill.KEY_ENTER ) + { + autofill.keyhandler(); + // window.console.info('Control key detected, called keyhandler and exiting'); + return true; + } + } + } + + if ( this.box_id ) + { + this.destroy(); + // window.console.info('already have a box open - destroying and exiting'); + //return false; + } + + var users = new Array(); + for ( var i = 0; i < resp_json.users_real.length; i++ ) + { + try + { + var user = resp_json.users_real[i].toLowerCase(); + var inp = $(autofill.field_id).object.value; + inp = inp.toLowerCase(); + if ( user.indexOf(inp) > -1 ) + { + users.push(resp_json.users_real[i]); + } + } + catch(e) + { + users.push(resp_json.users_real[i]); + } + } + + // This was used ONLY for debugging the DOM and list logic + // resp_json.users = resp_json.users_real; + + // construct table + var div = document.createElement('div'); + div.className = 'tblholder'; + div.style.clip = 'rect(0px,auto,auto,0px)'; + div.style.maxHeight = '200px'; + div.style.overflow = 'auto'; + div.style.zIndex = '9999'; + var table = document.createElement('table'); + table.border = '0'; + table.cellSpacing = '1'; + table.cellPadding = '3'; + + var tr = document.createElement('tr'); + var th = document.createElement('th'); + th.appendChild(document.createTextNode('Username suggestions')); + tr.appendChild(th); + table.appendChild(tr); + + if ( users.length < 1 ) + { + var tr = document.createElement('tr'); + var td = document.createElement('td'); + td.className = 'row1'; + td.appendChild(document.createTextNode('No suggestions')); + td.afobj = autofill; + tr.appendChild(td); + table.appendChild(tr); + } + else + + for ( var i = 0; i < users.length; i++ ) + { + var user = users[i]; + var tr = document.createElement('tr'); + var td = document.createElement('td'); + td.className = ( i == 0 ) ? 'row2' : 'row1'; + td.appendChild(document.createTextNode(user)); + td.afobj = autofill; + td.style.cursor = 'pointer'; + td.onclick = function() + { + this.afobj.set(this.firstChild.nodeValue); + } + tr.appendChild(td); + table.appendChild(tr); + } + + // Finalize div + var tb_top = $(autofill.field_id).Top(); + var tb_height = $(autofill.field_id).Height(); + var af_top = tb_top + tb_height - 9; + var tb_left = $(autofill.field_id).Left(); + var af_left = tb_left; + + div.style.position = 'absolute'; + div.style.left = af_left + 'px'; + div.style.top = af_top + 'px'; + div.style.width = '200px'; + div.style.fontSize = '7pt'; + div.style.fontFamily = 'Trebuchet MS, arial, helvetica, sans-serif'; + div.id = 'afuserdrop_' + Math.floor(Math.random() * 1000000); + div.appendChild(table); + + autofill.boxes.push(div.id); + autofill.box_id = div.id; + if ( users.length > 0 ) + autofill.state = users[0]; + + var body = document.getElementsByTagName('body')[0]; + body.appendChild(div); + + autofill.repeat = true; + } + + // perform ajax call + this.fetch_and_process = function() + { + af_current = this; + var processResponse = function() + { + if ( ajax.readyState == 4 ) + { + var afobj = af_current; + af_current = false; + // parse the JSON response + var response = String(ajax.responseText) + ' '; + if ( response.substr(0,1) != '{' ) + { + new messagebox(MB_OK|MB_ICONSTOP, 'Invalid response', 'Invalid or unexpected JSON response from server:
' + ajax.responseText + ''); + return false; + } + if ( $(afobj.field_id).object.value.length < 3 ) + return false; + var resp_json = parseJSON(response); + var resp_code = $(afobj.field_id).object.value.toLowerCase().substr(0, 3); + afobj.responses[resp_code] = resp_json; + afobj.process_dataset(resp_json); + } + } + var usernamefragment = ajaxEscape($(this.field_id).object.value); + ajaxGet(stdAjaxPrefix + '&_mode=fillusername&name=' + usernamefragment + '&allowanon=' + ( this.allowanon ? '1' : '0' ), processResponse); + } + + this.go = function() + { + if ( document.getElementById(this.field_id).value.length < 3 ) + { + this.destroy(); + return false; + } + + if ( af_current ) + return false; + + var resp_code = $(this.field_id).object.value.toLowerCase().substr(0, 3); + if ( this.responses.length < 1 || ! this.responses[ resp_code ] ) + { + // window.console.info('Cannot find dataset ' + resp_code + ' in cache, sending AJAX request'); + this.fetch_and_process(); + } + else + { + // window.console.info('Using cached dataset: ' + resp_code); + var resp_json = this.responses[ resp_code ]; + this.process_dataset(resp_json); + } + document.getElementById(this.field_id).onkeyup = function(event) + { + this.afobj.event = event; + this.afobj.go(); + } + document.getElementById(this.field_id).onkeydown = function(event) + { + var form = findParentForm(this); + if ( typeof(event) != 'object' ) + var event = window.event; + if ( typeof(event) == 'object' ) + { + if ( event.keyCode == this.afobj.KEY_ENTER && this.afobj.boxes.length < 1 && !this.afobj.box_id ) + { + // user hit enter after accepting a suggestion - submit the form + form._af_acting = false; + return true; + } + } + form._af_acting = true; + } + } + + this.keyhandler = function() + { + var key = this.event.keyCode; + if ( key == this.KEY_ENTER && !this.repeat ) + { + var form = findParentForm($(this.field_id).object); + form._af_acting = false; + return true; + } + switch(key) + { + case this.KEY_UP: + this.focus_up(); + break; + case this.KEY_DOWN: + this.focus_down(); + break; + case this.KEY_ESC: + this.destroy(); + break; + case this.KEY_TAB: + this.destroy(); + break; + case this.KEY_ENTER: + this.set(); + break; + } + + var form = findParentForm($(this.field_id).object); + form._af_acting = false; + } + + this.get_state_td = function() + { + var div = document.getElementById(this.box_id); + if ( !div ) + return false; + if ( !this.state ) + return false; + var table = div.firstChild; + for ( var i = 1; i < table.childNodes.length; i++ ) + { + // the table is DOM-constructed so no cruddy HTML hacks :-) + var child = table.childNodes[i]; + var tn = child.firstChild.firstChild; + if ( tn.nodeValue == this.state ) + return child.firstChild; + } + return false; + } + + this.focus_down = function() + { + var state_td = this.get_state_td(); + if ( !state_td ) + return false; + if ( state_td.parentNode.nextSibling ) + { + // Ooh boy, DOM stuff can be so complicated... + //
You need to be logged in to post comments. Log in
'; + $_ob .= 'You need to be logged in to post comments. Log in
'; } $list .= '};'; echo 'document.getElementById(\'ajaxEditContainer\').innerHTML = unescape(\''. rawurlencode($_ob) .'\'); @@ -1139,7 +1179,7 @@ if(!$session->get_permissions('mod_comments')) // allow mods to edit comments { if(!$session->user_logged_in) _die('AJAX comment save safety check failed because you are not logged in. Sometimes this can happen because you are using a browser that does not send cookies as part of AJAX requests.'.htmlspecialchars($q).''); $r = $db->fetchrow($s); @@ -1148,13 +1188,13 @@ } $s = RenderMan::preprocess_text($subject); $t = RenderMan::preprocess_text($text); - $sql = 'UPDATE '.table_prefix.'comments SET subject=\''.$s.'\',comment_data=\''.$t.'\' WHERE comment_data=\''.$old_text.'\' AND subject=\''.$old_subject.'\' AND page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\''; + $sql = 'UPDATE ' . table_prefix.'comments SET subject=\'' . $s . '\',comment_data=\'' . $t . '\' WHERE comment_data=\'' . $old_text . '\' AND subject=\'' . $old_subject . '\' AND page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\''; $result = $db->sql_query($sql); if($result) { return 'result="GOOD"; - list['.$id.'][\'subject\'] = unescape(\''.str_replace('%5Cn', '%0A', rawurlencode(str_replace('{{EnAnO:Newline}}', '\\n', stripslashes(str_replace('\\n', '{{EnAnO:Newline}}', $s))))).'\'); - list['.$id.'][\'comment\'] = unescape(\''.str_replace('%5Cn', '%0A', rawurlencode(str_replace('{{EnAnO:Newline}}', '\\n', stripslashes(str_replace('\\n', '{{EnAnO:Newline}}', $t))))).'\'); id = '.$id.'; + list[' . $id . '][\'subject\'] = unescape(\''.str_replace('%5Cn', '%0A', rawurlencode(str_replace('{{EnAnO:Newline}}', '\\n', stripslashes(str_replace('\\n', '{{EnAnO:Newline}}', $s))))).'\'); + list[' . $id . '][\'comment\'] = unescape(\''.str_replace('%5Cn', '%0A', rawurlencode(str_replace('{{EnAnO:Newline}}', '\\n', stripslashes(str_replace('\\n', '{{EnAnO:Newline}}', $t))))).'\'); id = ' . $id . '; s = unescape(\''.rawurlencode($s).'\'); t = unescape(\''.str_replace('%5Cn', '
'.htmlspecialchars($q).''); $r = $db->fetchrow($s); @@ -1197,13 +1237,13 @@ } $s = RenderMan::preprocess_text($subject); $t = RenderMan::preprocess_text($text); - $sql = 'UPDATE '.table_prefix.'comments SET subject=\''.$s.'\',comment_data=\''.$t.'\' WHERE comment_id='.$id.' AND page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\''; + $sql = 'UPDATE ' . table_prefix.'comments SET subject=\'' . $s . '\',comment_data=\'' . $t . '\' WHERE comment_id=' . $id . ' AND page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\''; $result = $db->sql_query($sql); if($result) return 'good'; else return 'Enano encountered a problem whilst saving the comment. Performed SQL: - '.$sql.' + ' . $sql . ' Error returned by MySQL: '.mysql_error(); } @@ -1235,16 +1275,16 @@ if(!$session->get_permissions('mod_comments')) // allows mods to delete comments { if(!$session->user_logged_in) _die('AJAX comment save safety check failed because you are not logged in. Sometimes this can happen because you are using a browser that does not send cookies as part of AJAX requests.
'.htmlspecialchars($q).''); $r = $db->fetchrow($s); if($db->numrows() < 1 || $r['name'] != $session->username) _die('Safety check failed, probably due to a hacking attempt.'); $db->free_result(); } - $q = 'DELETE FROM '.table_prefix.'comments WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\' AND name=\''.$n.'\' AND subject=\''.$s.'\' AND comment_data=\''.$t.'\' LIMIT 1;'; + $q = 'DELETE FROM ' . table_prefix.'comments WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\' AND name=\'' . $n . '\' AND subject=\'' . $s . '\' AND comment_data=\'' . $t . '\' LIMIT 1;'; $e=$db->sql_query($q); - if(!$e) return('alert(unesape(\''.rawurlencode('Error during query: '.mysql_error().'\n\nQuery:\n'.$q).'\'));'); + if(!$e) return('alert(unesape(\''.rawurlencode('Error during query: '.mysql_error().'\n\nQuery:\n' . $q) . '\'));'); return('good'); } @@ -1269,16 +1309,16 @@ if(!$session->get_permissions('mod_comments')) // allows mods to delete comments { if(!$session->user_logged_in) _die('AJAX comment save safety check failed because you are not logged in. Sometimes this can happen because you are using a browser that does not send cookies as part of AJAX requests.
'.htmlspecialchars($q).''); $r = $db->fetchrow($s); if($db->numrows() < 1 || $r['name'] != $session->username) _die('Safety check failed, probably due to a hacking attempt.'); $db->free_result(); } - $q = 'DELETE FROM '.table_prefix.'comments WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\' AND comment_id='.$id.' LIMIT 1;'; + $q = 'DELETE FROM ' . table_prefix.'comments WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\' AND comment_id=' . $id . ' LIMIT 1;'; $e=$db->sql_query($q); - if(!$e) return('alert(unesape(\''.rawurlencode('Error during query: '.mysql_error().'\n\nQuery:\n'.$q).'\'));'); + if(!$e) return('alert(unesape(\''.rawurlencode('Error during query: '.mysql_error().'\n\nQuery:\n' . $q) . '\'));'); return('good'); } @@ -1305,19 +1345,19 @@ } if( ( $session->get_permissions('rename') && ( ( $prot && $session->get_permissions('even_when_protected') ) || !$prot ) ) && ( $paths->namespace != 'Special' && $paths->namespace != 'Admin' )) { - $e = $db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,page_id,namespace,author,edit_summary) VALUES('.time().', \''.date('d M Y h:i a').'\', \'page\', \'rename\', \''.$db->escape($paths->cpage['urlname_nons']).'\', \''.$paths->namespace.'\', \''.$db->escape($session->username).'\', \''.$db->escape($paths->cpage['name']).'\')'); + $e = $db->sql_query('INSERT INTO ' . table_prefix.'logs(time_id,date_string,log_type,action,page_id,namespace,author,edit_summary) VALUES('.time().', \''.date('d M Y h:i a').'\', \'page\', \'rename\', \'' . $db->escape($paths->cpage['urlname_nons']) . '\', \'' . $paths->namespace . '\', \'' . $db->escape($session->username) . '\', \'' . $db->escape($paths->cpage['name']) . '\')'); if ( !$e ) { $db->_die('The page title could not be updated.'); } - $e = $db->sql_query('UPDATE '.table_prefix.'pages SET name=\''.$db->escape($name).'\' WHERE urlname=\''.$db->escape($page_id).'\' AND namespace=\''.$db->escape($namespace).'\';'); + $e = $db->sql_query('UPDATE ' . table_prefix.'pages SET name=\'' . $db->escape($name) . '\' WHERE urlname=\'' . $db->escape($page_id) . '\' AND namespace=\'' . $db->escape($namespace) . '\';'); if ( !$e ) { $db->_die('The page title could not be updated.'); } else { - return('The page "'.$paths->pages[$pname]['name'].'" has been renamed to "'.$name.'". You are encouraged to leave a comment explaining your action.' . "\n\n" . 'You will see the change take effect the next time you reload this page.'); + return('The page "' . $paths->pages[$pname]['name'] . '" has been renamed to "' . $name . '". You are encouraged to leave a comment explaining your action.' . "\n\n" . 'You will see the change take effect the next time you reload this page.'); } } else @@ -1337,18 +1377,18 @@ { global $db, $session, $paths, $template, $plugins; // Common objects if(!$session->get_permissions('clear_logs')) die('Administrative privileges are required to flush logs, you loser.'); - $e = $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE page_id=\''.$db->escape($page_id).'\' AND namespace=\''.$db->escape($namespace).'\';'); + $e = $db->sql_query('DELETE FROM ' . table_prefix.'logs WHERE page_id=\'' . $db->escape($page_id) . '\' AND namespace=\'' . $db->escape($namespace) . '\';'); if(!$e) $db->_die('The log entries could not be deleted.'); // If the page exists, make a backup of it in case it gets spammed/vandalized // If not, the admin's probably deleting a trash page if ( isset($paths->pages[ $paths->nslist[$namespace] . $page_id ]) ) { - $e = $db->sql_query('SELECT page_text,char_tag FROM '.table_prefix.'page_text WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\';'); + $e = $db->sql_query('SELECT page_text,char_tag FROM ' . table_prefix.'page_text WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\';'); if(!$e) $db->_die('The current page text could not be selected; as a result, creating the backup of the page failed. Please make a backup copy of the page by clicking Edit this page and then clicking Save Changes.'); $row = $db->fetchrow(); $db->free_result(); - $q='INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,page_id,namespace,page_text,char_tag,author,edit_summary,minor_edit) VALUES(\'page\', \'edit\', '.time().', \''.date('d M Y h:i a').'\', \''.$page_id.'\', \''.$namespace.'\', \''.$db->escape($row['page_text']).'\', \''.$row['char_tag'].'\', \''.$session->username.'\', \''."Automatic backup created when logs were purged".'\', '.'false'.');'; + $q='INSERT INTO ' . table_prefix.'logs(log_type,action,time_id,date_string,page_id,namespace,page_text,char_tag,author,edit_summary,minor_edit) VALUES(\'page\', \'edit\', '.time().', \''.date('d M Y h:i a').'\', \'' . $page_id . '\', \'' . $namespace . '\', \'' . $db->escape($row['page_text']) . '\', \'' . $row['char_tag'] . '\', \'' . $session->username . '\', \''."Automatic backup created when logs were purged".'\', '.'false'.');'; if(!$db->sql_query($q)) $db->_die('The history (log) entry could not be inserted into the logs table.'); } return('The logs for this page have been cleared. A backup of this page has been added to the logs table so that this page can be restored in case of vandalism or spam later.'); @@ -1372,17 +1412,17 @@ return 'Invalid reason for deletion passed'; } if(!$perms->get_permissions('delete_page')) return('Administrative privileges are required to delete pages, you loser.'); - $e = $db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,page_id,namespace,author,edit_summary) VALUES('.time().', \''.date('d M Y h:i a').'\', \'page\', \'delete\', \''.$page_id.'\', \''.$namespace.'\', \''.$session->username.'\', \'' . $db->escape(htmlspecialchars($reason)) . '\')'); + $e = $db->sql_query('INSERT INTO ' . table_prefix.'logs(time_id,date_string,log_type,action,page_id,namespace,author,edit_summary) VALUES('.time().', \''.date('d M Y h:i a').'\', \'page\', \'delete\', \'' . $page_id . '\', \'' . $namespace . '\', \'' . $session->username . '\', \'' . $db->escape(htmlspecialchars($reason)) . '\')'); if(!$e) $db->_die('The page log entry could not be inserted.'); - $e = $db->sql_query('DELETE FROM '.table_prefix.'categories WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\''); + $e = $db->sql_query('DELETE FROM ' . table_prefix.'categories WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\''); if(!$e) $db->_die('The page categorization entries could not be deleted.'); - $e = $db->sql_query('DELETE FROM '.table_prefix.'comments WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\''); + $e = $db->sql_query('DELETE FROM ' . table_prefix.'comments WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\''); if(!$e) $db->_die('The page comments could not be deleted.'); - $e = $db->sql_query('DELETE FROM '.table_prefix.'page_text WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\''); + $e = $db->sql_query('DELETE FROM ' . table_prefix.'page_text WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\''); if(!$e) $db->_die('The page text entry could not be deleted.'); - $e = $db->sql_query('DELETE FROM '.table_prefix.'pages WHERE urlname=\''.$page_id.'\' AND namespace=\''.$namespace.'\''); + $e = $db->sql_query('DELETE FROM ' . table_prefix.'pages WHERE urlname=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\''); if(!$e) $db->_die('The page entry could not be deleted.'); - $e = $db->sql_query('DELETE FROM '.table_prefix.'files WHERE page_id=\''.$page_id.'\''); + $e = $db->sql_query('DELETE FROM ' . table_prefix.'files WHERE page_id=\'' . $page_id . '\''); if(!$e) $db->_die('The file entry could not be deleted.'); return('This page has been deleted. Note that there is still a log of edits and actions in the database, and anyone with admin rights can raise this page from the dead unless the log is cleared. If the deleted file is an image, there may still be cached thumbnails of it in the cache/ directory, which is inaccessible to users.'); } @@ -1447,7 +1487,7 @@ $cv++; - $q = 'UPDATE '.table_prefix.'pages SET delvotes='.$cv.',delvote_ips=\''.$ips.'\' WHERE urlname=\''.$page_id.'\' AND namespace=\''.$namespace.'\''; + $q = 'UPDATE ' . table_prefix.'pages SET delvotes=' . $cv . ',delvote_ips=\'' . $ips . '\' WHERE urlname=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\''; $w = $db->sql_query($q); return 'Your vote to have this page deleted has been cast.'."\nYou are encouraged to leave a comment explaining the reason for your vote."; @@ -1464,7 +1504,7 @@ { global $db, $session, $paths, $template, $plugins; // Common objects if(!$session->get_permissions('vote_reset')) die('You need moderator rights in order to do this, stinkin\' hacker.'); - $q = 'UPDATE '.table_prefix.'pages SET delvotes=0,delvote_ips=\'' . $db->escape(serialize(array('ip'=>array(),'u'=>array()))) . '\' WHERE urlname=\''.$page_id.'\' AND namespace=\''.$namespace.'\''; + $q = 'UPDATE ' . table_prefix.'pages SET delvotes=0,delvote_ips=\'' . $db->escape(serialize(array('ip'=>array(),'u'=>array()))) . '\' WHERE urlname=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\''; $e = $db->sql_query($q); if(!$e) $db->_die('The number of delete votes was not reset.'); else return('The number of votes for having this page deleted has been reset to zero.'); @@ -1480,14 +1520,17 @@ { $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); - $dir = './themes/'.$_GET['id'].'/css/'; + if ( !preg_match('/^([a-z0-9_-]+)$/', $_GET['id']) ) + return $json->encode(false); + + $dir = './themes/' . $_GET['id'] . '/css/'; $list = Array(); // Open a known directory, and proceed to read its contents if (is_dir($dir)) { if ($dh = opendir($dir)) { while (($file = readdir($dh)) !== false) { - if(preg_match('#^(.*?)\.css$#is', $file) && $file != '_printable.css') { // _printable.css should be included with every theme - // it should be a copy of the original style, but + if ( preg_match('#^(.*?)\.css$#is', $file) && $file != '_printable.css' ) // _printable.css should be included with every theme + { // it should be a copy of the original style, but // mostly black and white // Note to self: document this $list[] = substr($file, 0, strlen($file)-4); @@ -1527,7 +1570,7 @@ global $db, $session, $paths, $template, $plugins; // Common objects ob_start(); $_ob = ''; - $e = $db->sql_query('SELECT category_id FROM '.table_prefix.'categories WHERE page_id=\''.$paths->cpage['urlname_nons'].'\' AND namespace=\''.$paths->namespace.'\''); + $e = $db->sql_query('SELECT category_id FROM ' . table_prefix.'categories WHERE page_id=\'' . $paths->cpage['urlname_nons'] . '\' AND namespace=\'' . $paths->namespace . '\''); if(!$e) jsdie('Error selecting category information for current page: '.mysql_error()); $cat_current = Array(); while($r = $db->fetchrow()) @@ -1579,10 +1622,10 @@ $is_prot = true; $prot = ( $is_prot ) ? ' disabled="disabled" ' : ''; $prottext = ( $is_prot ) ? ' ' : ''; - echo 'catlist['.$i.'] = \''.$cat_info[$i]['urlname_nons'].'\';'; - $_ob .= ''.$cat_info[$i]['name'].$prottext.'
'.print_r($linklist, true).''; - for($i=0;$i
' . print_r($matches, true) . ''); for ( $i = 0; $i < $count; $i++ ) { $matches[1][$i] = sanitize_page_id($matches[1][$i]); @@ -620,10 +594,9 @@ if ( !empty($parmsection) ) { $parms = RenderMan::parse_template_vars($parmsection); - foreach ( $parms as $j => $parm ) - { - $parms[$j] = $parm; - } + if ( !is_array($parms) ) + // Syntax error + $parms = array(); } else { @@ -735,6 +708,7 @@ ':-/' => 'face-plain.png', ':joke:' => 'face-plain.png', ']:->' => 'face-devil-grin.png', + ']:->' => 'face-devil-grin.png', ':kiss:' => 'face-kiss.png', ':-P' => 'face-tongue-out.png', ':P' => 'face-tongue-out.png', diff -r db8a849ad4c9 -r eec079676fe7 includes/sessions.php --- a/includes/sessions.php Sat Oct 06 20:36:52 2007 -0400 +++ b/includes/sessions.php Sat Oct 20 21:51:26 2007 -0400 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.1.1 + * Version 1.0.2 (Coblynau) * Copyright (C) 2006-2007 Dan Fuhry * sessions.php - everything related to security and user management * @@ -585,13 +585,12 @@ $this->sql('SELECT password,old_encryption,user_id,user_level,theme,style,temp_password,temp_password_time FROM '.table_prefix.'users WHERE lcase(username)=\''.$db_username_lower.'\' OR username=\'' . $db_username . '\';'); if($db->numrows() < 1) { - return "The username and/or password is incorrect.\n$db->latest_query"; // This wasn't logged in <1.0.2, dunno how it slipped through if($level > USER_LEVEL_MEMBER) $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_bad\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); else $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_bad\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); - + return "The username and/or password is incorrect."; } $row = $db->fetchrow(); @@ -708,8 +707,15 @@ // Retrieve the real password from the database $this->sql('SELECT password,old_encryption,user_id,user_level,temp_password,temp_password_time FROM '.table_prefix.'users WHERE lcase(username)=\''.$this->prepare_text(strtolower($username)).'\';'); - if($db->numrows() < 1) - return 'The username and/or password is incorrect.'; + if ( $db->numrows() < 1 ) + { + // This wasn't logged in <1.0.2, dunno how it slipped through + if($level > USER_LEVEL_MEMBER) + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_bad\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); + else + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_bad\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); + return "The username and/or password is incorrect."; + } $row = $db->fetchrow(); // Check to see if we're logging in using a temporary password diff -r db8a849ad4c9 -r eec079676fe7 includes/template.php --- a/includes/template.php Sat Oct 06 20:36:52 2007 -0400 +++ b/includes/template.php Sat Oct 20 21:51:26 2007 -0400 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.1.1 + * Version 1.0.2 (Coblynau) * Copyright (C) 2006-2007 Dan Fuhry * * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License @@ -783,7 +783,13 @@ dc_here('template: generating and sending the page header'); if(!defined('ENANO_HEADERS_SENT')) define('ENANO_HEADERS_SENT', ''); - if(!$this->no_headers) echo ( $simple ) ? $this->process_template('simple-header.tpl') : $this->process_template('header.tpl'); + if ( !$this->no_headers ) + { + $header = ( $simple ) ? + $this->process_template('simple-header.tpl') : + $this->process_template('header.tpl'); + echo $header; + } if ( !$simple && $session->user_logged_in && $session->unread_pms > 0 ) { echo $this->notify_unread_pms(); @@ -952,6 +958,7 @@ function compile_tpl_code($text) { + global $db, $session, $paths, $template, $plugins; // Common objects // A random seed used to salt tags $seed = md5 ( microtime() . mt_rand() ); @@ -980,29 +987,88 @@ // Conditionals // - // If-else-end - $text = preg_replace('/(.*?)(.*?)/is', '\'; if ( $this->tpl_bool[\'\\1\'] ) { echo \'\\2\'; } else { echo \'\\3\'; } echo \'', $text); - - // If-end - $text = preg_replace('/(.*?)/is', '\'; if ( $this->tpl_bool[\'\\1\'] ) { echo \'\\2\'; } echo \'', $text); + $keywords = array('BEGIN', 'BEGINNOT', 'IFSET', 'IFPLUGIN'); + $code = $plugins->setHook('template_compile_logic_keyword'); + foreach ( $code as $cmd ) + { + eval($cmd); + } - // If not-else-end - $text = preg_replace('/(.*?)(.*?)/is', '\'; if ( !$this->tpl_bool[\'\\1\'] ) { echo \'\\2\'; } else { echo \'\\3\'; } echo \'', $text); + $keywords = implode('|', $keywords); - // If not-end - $text = preg_replace('/(.*?)/is', '\'; if ( !$this->tpl_bool[\'\\1\'] ) { echo \'\\2\'; } echo \'', $text); + // Matches + // 1 2 3 4 56 7 8 + $regexp = '/()(.*)(()(.*))?()/isU'; + + /* + The way this works is: match all blocks using the standard form with a different keyword in the block each time, + and replace them with appropriate PHP logic. Plugin-extensible now. :-) - // If set-else-end - $text = preg_replace('/(.*?)(.*?)/is', '\'; if ( isset($this->tpl_strings[\'\\1\']) ) { echo \'\\2\'; } else { echo \'\\3\'; } echo \'', $text); - - // If set-end - $text = preg_replace('/(.*?)/is', '\'; if ( isset($this->tpl_strings[\'\\1\']) ) { echo \'\\2\'; } echo \'', $text); + The while-loop is to bypass what is apparently a PCRE bug. It's hackish but it works. Properly written plugins should only need + to compile templates (using this method) once for each time the template file is changed. + */ + while ( preg_match($regexp, $text) ) + { + preg_match_all($regexp, $text, $matches); + for ( $i = 0; $i < count($matches[0]); $i++ ) + { + $start_tag =& $matches[1][$i]; + $type =& $matches[2][$i]; + $test =& $matches[3][$i]; + $particle_true =& $matches[4][$i]; + $else_tag =& $matches[6][$i]; + $particle_else =& $matches[7][$i]; + $end_tag =& $matches[8][$i]; + + switch($type) + { + case 'BEGIN': + $cond = "isset(\$this->tpl_bool['$test']) && \$this->tpl_bool['$test']"; + break; + case 'BEGINNOT': + $cond = "!isset(\$this->tpl_bool['$test']) || ( isset(\$this->tpl_bool['$test']) && !\$this->tpl_bool['$test'] )"; + break; + case 'IFPLUGIN': + $cond = "getConfig('plugin_$test') == '1'"; + break; + case 'IFSET': + $cond = "isset(\$this->tpl_strings['$test'])"; + break; + default: + $code = $plugins->setHook('template_compile_logic_cond'); + foreach ( $code as $cmd ) + { + eval($cmd); + } + break; + } + + if ( !isset($cond) || ( isset($cond) && !is_string($cond) ) ) + continue; + + $tag_complete = <<
<?php\n" . htmlspecialchars($text."\n\n".print_r($matches,true)) . "\n\n?>"); // // Data substitution/variables @@ -1023,6 +1089,8 @@ $text = str_replace_once($tag, "'; $match echo '", $text); } + // echo('
' . htmlspecialchars($text) . ''); + return $text; } @@ -1405,7 +1473,7 @@ function username_field($name, $value = false) { $randomid = md5( time() . microtime() . mt_rand() ); - $text = 'View the text of this license
Hacking attempt
'); } - $q = $db->sql_query('SELECT group_name,group_type FROM '.table_prefix.'groups WHERE group_id=' . $gid . ';'); + $q = $db->sql_query('SELECT group_name,group_type,system_group FROM '.table_prefix.'groups WHERE group_id=' . $gid . ';'); if ( !$q ) { - $db->_die(); + $db->_die('SpecialGroups.php, line ' . __LINE__); } $row = $db->fetchrow(); $db->free_result(); @@ -70,7 +70,7 @@ ORDER BY m.is_mod DESC,u.username ASC;'); if ( !$q ) { - $db->_die(); + $db->_die('SpecialGroups.php, line ' . __LINE__); } $is_member = false; @@ -127,11 +127,29 @@ { die_friendly('ERROR', 'Hacking attempt
'); } - $q = $db->sql_query('UPDATE '.table_prefix.'groups SET group_type=' . intval($_POST['group_state']) . ' WHERE group_id=' . intval( $_POST['group_id']) . ';'); - if (!$q) - $db->_die(); - $row['group_type'] = $_POST['group_state']; - echo 'The page title can\'t start with "Project:" because this prefix is reserved for a parser shortcut.
'; + + $template->footer(); + $db->close(); + + exit; + } $tn = $paths->nslist[$_POST['namespace']] . $urlname; if ( isset($paths->pages[$tn]) ) diff -r db8a849ad4c9 -r eec079676fe7 plugins/SpecialSearch.php --- a/plugins/SpecialSearch.php Sat Oct 06 20:36:52 2007 -0400 +++ b/plugins/SpecialSearch.php Sat Oct 20 21:51:26 2007 -0400 @@ -4,13 +4,13 @@ Plugin URI: http://enanocms.org/ Description: Provides the page Special:Search, which is a frontend to the Enano search engine. Author: Dan Fuhry -Version: 1.0.1 +Version: 1.0.2 Author URI: http://enanocms.org/ */ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0 release candidate 2 + * Version 1.0.2 * Copyright (C) 2006-2007 Dan Fuhry * * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License @@ -100,18 +100,21 @@ if(!empty($q)) { // See if any pages directly match the title - - for ( $i = 0; $i < count ( $paths->pages ) / 2; $i++ ) + + if ( strlen($q) >= 4 ) { - $pg =& $paths->pages[$i]; - $q_lc = strtolower( str_replace(' ', '_', $q) ); - $q_tl = strtolower( str_replace('_', ' ', $q) ); - $p_lc = strtolower($pg['urlname']); - $p_tl = strtolower($pg['name']); - if ( strstr($p_tl, $q_tl) || strstr($p_lc, $q_lc) && $pg['visible'] == 1 ) + for ( $i = 0; $i < count ( $paths->pages ) / 2; $i++ ) { - echo ' '; - break; + $pg =& $paths->pages[$i]; + $q_lc = strtolower( str_replace(' ', '_', $q) ); + $q_tl = strtolower( str_replace('_', ' ', $q) ); + $p_lc = strtolower($pg['urlname']); + $p_tl = strtolower($pg['name']); + if ( strstr($p_tl, $q_tl) || strstr($p_lc, $q_lc) && $pg['visible'] == 1 ) + { + echo ' '; + break; + } } } diff -r db8a849ad4c9 -r eec079676fe7 plugins/SpecialUpdownload.php --- a/plugins/SpecialUpdownload.php Sat Oct 06 20:36:52 2007 -0400 +++ b/plugins/SpecialUpdownload.php Sat Oct 20 21:51:26 2007 -0400 @@ -4,13 +4,13 @@ Plugin URI: http://enanocms.org/ Description: Provides the pages Special:UploadFile and Special:DownloadFile. UploadFile is used to upload files to the site, and DownloadFile fetches the file from the database, creates thumbnails if necessary, and sends the file to the user. Author: Dan Fuhry -Version: 1.0.1 +Version: 1.0.2 Author URI: http://enanocms.org/ */ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0 release candidate 2 + * Version 1.0.2 * Copyright (C) 2006-2007 Dan Fuhry * SpecialUpdownload.php - handles uploading and downloading of user-uploaded files - possibly the most rigorously security-enforcing script in all of Enano, although sessions.php comes in a close second * @@ -59,8 +59,14 @@ { $file = false; } - if(!is_array($file)) die_friendly('Upload failed', 'The server could not retrieve the array $_FILES[\'data\'].
'); - if($file['size'] == 0 || $file['size'] > (int)getConfig('max_file_size')) die_friendly('Upload failed', 'The file you uploaded is either too large or 0 bytes in length.
'); + if ( !is_array($file) ) + { + die_friendly('Upload failed', 'The server could not retrieve the array $_FILES[\'data\'].
'); + } + if ( $file['size'] == 0 || $file['size'] > (int)getConfig('max_file_size') ) + { + die_friendly('Upload failed', 'The file you uploaded is either too large or 0 bytes in length.
'); + } /* $allowed_mime_types = Array( 'text/plain', @@ -88,7 +94,7 @@ */ $types = fetch_allowed_extensions(); $ext = substr($file['name'], strrpos($file['name'], '.')+1, strlen($file['name'])); - if(!isset($types[$ext]) || ( isset($types[$ext]) && !$types[$ext] ) ) + if ( !isset($types[$ext]) || ( isset($types[$ext]) && !$types[$ext] ) ) { die_friendly('Upload failed', 'The file type ".'.$ext.'" is not allowed.
'); } diff -r db8a849ad4c9 -r eec079676fe7 plugins/SpecialUserFuncs.php --- a/plugins/SpecialUserFuncs.php Sat Oct 06 20:36:52 2007 -0400 +++ b/plugins/SpecialUserFuncs.php Sat Oct 20 21:51:26 2007 -0400 @@ -4,13 +4,13 @@ Plugin URI: http://enanocms.org/ Description: Provides the pages Special:Login, Special:Logout, Special:Register, and Special:Preferences. Author: Dan Fuhry -Version: 1.0.1 +Version: 1.0.2 Author URI: http://enanocms.org/ */ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0 release candidate 2 + * Version 1.0.2 * Copyright (C) 2006-2007 Dan Fuhry * * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License diff -r db8a849ad4c9 -r eec079676fe7 plugins/SpecialUserPrefs.php --- a/plugins/SpecialUserPrefs.php Sat Oct 06 20:36:52 2007 -0400 +++ b/plugins/SpecialUserPrefs.php Sat Oct 20 21:51:26 2007 -0400 @@ -4,13 +4,13 @@ Plugin URI: http://enanocms.org/ Description: Provides the page Special:Preferences. Author: Dan Fuhry -Version: 1.0.1 +Version: 1.0.2 Author URI: http://enanocms.org/ */ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0 release candidate 2 + * Version 1.0.2 * Copyright (C) 2006-2007 Dan Fuhry * * This program is Free Software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -100,7 +100,7 @@ global $db, $session, $paths, $template, $plugins; // Common objects global $userprefs_menu_links; - userprefs_menu_add('Profile/membership', 'Edit e-mail address and password', makeUrlNS('Special', 'Preferences/EmailPassword')); + userprefs_menu_add('Profile/membership', 'Edit e-mail address and password', makeUrlNS('Special', 'Preferences/EmailPassword') . '" onclick="ajaxLoginNavTo(\'Special\', \'Preferences/EmailPassword\', '.USER_LEVEL_CHPREF.'); return false;'); userprefs_menu_add('Profile/membership', 'Edit signature', makeUrlNS('Special', 'Preferences/Signature')); userprefs_menu_add('Profile/membership', 'Edit public profile', makeUrlNS('Special', 'Preferences/Profile')); userprefs_menu_add('Private messages', 'Inbox', makeUrlNS('Special', 'PrivateMessages/Folder/Inbox')); @@ -302,11 +302,14 @@ { case 'Home': global $email; - $user_page = 'user page (comments)'; + $userpage_id = $paths->nslist['User'] . sanitize_page_id($session->username); + $userpage_exists = ( isPage($userpage_id) ) ? '' : ' class="wikilink-nonexistent"'; + $user_page = 'user page (comments)'; $site_admin = $email->encryptEmail(getConfig('contact_email'), '', '', 'administrator'); + $make_one_now = 'make one now'; echo "Here you can make changes to your profile, view statistics on yourself on this site, and set your preferences.
-If you have not already done so, you are encouraged to make a $user_page and tell the other members of this site a little about yourself.
+Your $user_page is your free writing space. You can use it to tell the other members of this site a little bit about yourself. If you haven't already made a user page, why not $make_one_now?
Use the menu at the top to navigate around. If you have any questions, you may contact the $site_admin."; break; case 'EmailPassword': diff -r db8a849ad4c9 -r eec079676fe7 plugins/admin/PageGroups.php --- a/plugins/admin/PageGroups.php Sat Oct 06 20:36:52 2007 -0400 +++ b/plugins/admin/PageGroups.php Sat Oct 20 21:51:26 2007 -0400 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.1.1 + * Version 1.0.2 (Coblynau) * Copyright (C) 2006-2007 Dan Fuhry * * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License @@ -602,6 +602,23 @@ echo '