diff options
author | Nathan Kinkade <nkinkade@nkinka.de> | 2010-05-13 01:49:54 +0000 |
---|---|---|
committer | Nathan Kinkade <nkinkade@nkinka.de> | 2010-05-13 01:49:54 +0000 |
commit | a0b0b415515bff5f9edd43d373e8e78f3b3f8e4d (patch) | |
tree | a101f7a71a33f75c21d4ac828f442d902f5d8af9 | |
parent | 104430e9e1e8dacd5e4320e29e59fc59aa5c6ee9 (diff) | |
parent | 9affa8ebbd539396d71f19003b91af577a8a183e (diff) |
Merge branch 'master' of git://github.com/gallery/gallery3
68 files changed, 517 insertions, 280 deletions
diff --git a/lib/flowplayer.controls.swf b/lib/flowplayer.controls.swf Binary files differindex 09a27e8a..aacdcd30 100644 --- a/lib/flowplayer.controls.swf +++ b/lib/flowplayer.controls.swf diff --git a/lib/flowplayer.h264streaming.swf b/lib/flowplayer.h264streaming.swf Binary files differdeleted file mode 100644 index 13c17a92..00000000 --- a/lib/flowplayer.h264streaming.swf +++ /dev/null diff --git a/lib/flowplayer.js b/lib/flowplayer.js index d4b619c3..57f00e65 100644 --- a/lib/flowplayer.js +++ b/lib/flowplayer.js @@ -51,7 +51,7 @@ return playlist[index];},getCommonClip:function(){return commonClip;},getPlaylis return plugin;},getScreen:function(){return self.getPlugin("screen");},getControls:function(){return self.getPlugin("controls");},getConfig:function(copy){return copy?clone(conf):conf;},getFlashParams:function(){return params;},loadPlugin:function(name,url,props,fn){if(typeof props=='function'){fn=props;props={};} var fnId=fn?makeId():"_";self._api().fp_loadPlugin(name,url,props,fnId);var arg={};arg[fnId]=fn;var p=new Plugin(name,null,self,arg);plugins[name]=p;return p;},getState:function(){return api?api.fp_getState():-1;},play:function(clip,instream){function play(){if(clip!==undefined){self._api().fp_play(clip,instream);}else{self._api().fp_play();}} if(api){play();}else{self.load(function(){play();});} -return self;},getVersion:function(){var js="flowplayer.js @VERSION";if(api){var ver=api.fp_getVersion();ver.push(js);return ver;} +return self;},getVersion:function(){var js="flowplayer.js 3.1.4";if(api){var ver=api.fp_getVersion();ver.push(js);return ver;} return js;},_api:function(){if(!api){throw"Flowplayer "+self.id()+" not loaded when calling an API method";} return api;},setClip:function(clip){self.setPlaylist([clip]);return self;},getIndex:function(){return playerIndex;}});each(("Click*,Load*,Unload*,Keypress*,Volume*,Mute*,Unmute*,PlaylistReplace,ClipAdd,Fullscreen*,FullscreenExit,Error,MouseOver,MouseOut").split(","),function(){var name="on"+this;if(name.indexOf("*")!=-1){name=name.substring(0,name.length-1);var name2="onBefore"+name.substring(2);self[name2]=function(fn){bind(listeners,name2,fn);return self;};} self[name]=function(fn){bind(listeners,name,fn);return self;};});each(("pause,resume,mute,unmute,stop,toggle,seek,getStatus,getVolume,setVolume,getTime,isPaused,isPlaying,startBuffering,stopBuffering,isFullscreen,toggleFullscreen,reset,close,setPlaylist,addClip,playFeed").split(","),function(){var name=this;self[name]=function(a1,a2){if(!api){return self;} diff --git a/lib/flowplayer.pseudostreaming.swf b/lib/flowplayer.pseudostreaming.swf Binary files differnew file mode 100644 index 00000000..91b3fdd6 --- /dev/null +++ b/lib/flowplayer.pseudostreaming.swf diff --git a/lib/flowplayer.swf b/lib/flowplayer.swf Binary files differindex 61d7f652..63f3934a 100644 --- a/lib/flowplayer.swf +++ b/lib/flowplayer.swf diff --git a/lib/yui/base-min.css b/lib/yui/base-min.css index 07014324..6eaa2606 100644 --- a/lib/yui/base-min.css +++ b/lib/yui/base-min.css @@ -1,7 +1,7 @@ /* -Copyright (c) 2008, Yahoo! Inc. All rights reserved. +Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: -http://developer.yahoo.net/yui/license.txt -version: 2.6.0 +http://developer.yahoo.com/yui/license.html +version: 2.8.1 */ -h1{font-size:138.5%;}h2{font-size:123.1%;}h3{font-size:108%;}h1,h2,h3{margin:1em 0;}h1,h2,h3,h4,h5,h6,strong{font-weight:bold;}abbr,acronym{border-bottom:1px dotted #000;cursor:help;} em{font-style:italic;}blockquote,ul,ol,dl{margin:1em;}ol,ul,dl{margin-left:2em;}ol li{list-style:decimal outside;}ul li{list-style:disc outside;}dl dd{margin-left:1em;}th,td{border:1px solid #000;padding:.5em;}th{font-weight:bold;text-align:center;}caption{margin-bottom:.5em;text-align:center;}p,fieldset,table,pre{margin-bottom:1em;}input[type=text],input[type=password],textarea{width:12.25em;*width:11.9em;} +body{margin:10px;}h1{font-size:138.5%;}h2{font-size:123.1%;}h3{font-size:108%;}h1,h2,h3{margin:1em 0;}h1,h2,h3,h4,h5,h6,strong,dt{font-weight:bold;}optgroup{font-weight:normal;}abbr,acronym{border-bottom:1px dotted #000;cursor:help;}em{font-style:italic;}del{text-decoration:line-through;}blockquote,ul,ol,dl{margin:1em;}ol,ul,dl{margin-left:2em;}ol li{list-style:decimal outside;}ul li{list-style:disc outside;}dl dd{margin-left:1em;}th,td{border:1px solid #000;padding:.5em;}th{font-weight:bold;text-align:center;}caption{margin-bottom:.5em;text-align:center;}sup{vertical-align:super;}sub{vertical-align:sub;}p,fieldset,table,pre{margin-bottom:1em;}button,input[type="checkbox"],input[type="radio"],input[type="reset"],input[type="submit"]{padding:1px;}
\ No newline at end of file diff --git a/lib/yui/reset-fonts-grids.css b/lib/yui/reset-fonts-grids.css index b3e042c9..03c7d9d8 100644 --- a/lib/yui/reset-fonts-grids.css +++ b/lib/yui/reset-fonts-grids.css @@ -1,7 +1,7 @@ /* -Copyright (c) 2008, Yahoo! Inc. All rights reserved. +Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: -http://developer.yahoo.net/yui/license.txt -version: 2.6.0 +http://developer.yahoo.com/yui/license.html +version: 2.8.1 */ -html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}del,ins{text-decoration:none;}body{font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}select,input,button,textarea{font:99% arial,helvetica,clean,sans-serif;}table{font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}body{text-align:center;}#ft{clear:both;}#doc,#doc2,#doc3,#doc4,.yui-t1,.yui-t2,.yui-t3,.yui-t4,.yui-t5,.yui-t6,.yui-t7{margin:auto;text-align:left;width:57.69em;*width:56.25em;min-width:750px;}#doc2{width:73.076em;*width:71.25em;}#doc3{margin:auto 10px;width:auto;}#doc4{width:74.923em;*width:73.05em;}.yui-b{position:relative;}.yui-b{_position:static;}#yui-main .yui-b{position:static;}#yui-main,.yui-g .yui-u .yui-g{width:100%;}{width:100%;}.yui-t1 #yui-main,.yui-t2 #yui-main,.yui-t3 #yui-main{float:right;margin-left:-25em;}.yui-t4 #yui-main,.yui-t5 #yui-main,.yui-t6 #yui-main{float:left;margin-right:-25em;}.yui-t1 .yui-b{float:left;width:12.30769em;*width:12.00em;}.yui-t1 #yui-main .yui-b{margin-left:13.30769em;*margin-left:13.05em;}.yui-t2 .yui-b{float:left;width:13.8461em;*width:13.50em;}.yui-t2 #yui-main .yui-b{margin-left:14.8461em;*margin-left:14.55em;}.yui-t3 .yui-b{float:left;width:23.0769em;*width:22.50em;}.yui-t3 #yui-main .yui-b{margin-left:24.0769em;*margin-left:23.62em;}.yui-t4 .yui-b{float:right;width:13.8456em;*width:13.50em;}.yui-t4 #yui-main .yui-b{margin-right:14.8456em;*margin-right:14.55em;}.yui-t5 .yui-b{float:right;width:18.4615em;*width:18.00em;}.yui-t5 #yui-main .yui-b{margin-right:19.4615em;*margin-right:19.125em;}.yui-t6 .yui-b{float:right;width:23.0769em;*width:22.50em;}.yui-t6 #yui-main .yui-b{margin-right:24.0769em;*margin-right:23.62em;}.yui-t7 #yui-main .yui-b{display:block;margin:0 0 1em 0;}#yui-main .yui-b{float:none;width:auto;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf,.yui-gc .yui-u,.yui-gd .yui-g,.yui-g .yui-gc .yui-u,.yui-ge .yui-u,.yui-ge .yui-g,.yui-gf .yui-g,.yui-gf .yui-u{float:right;}.yui-g div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first,.yui-ge div.first,.yui-gf div.first,.yui-g .yui-gc div.first,.yui-g .yui-ge div.first,.yui-gc div.first div.first{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf{width:49.1%;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{width:32%;margin-left:1.99%;}.yui-gb .yui-u{*margin-left:1.9%;*width:31.9%;}.yui-gc div.first,.yui-gd .yui-u{width:66%;}.yui-gd div.first{width:32%;}.yui-ge div.first,.yui-gf .yui-u{width:74.2%;}.yui-ge .yui-u,.yui-gf div.first{width:24%;}.yui-g .yui-gb div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first{margin-left:0;}.yui-g .yui-g .yui-u,.yui-gb .yui-g .yui-u,.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u,.yui-ge .yui-g .yui-u,.yui-gf .yui-g .yui-u{width:49%;*width:48.1%;*margin-left:0;}.yui-g .yui-g .yui-u{width:48.1%;}.yui-g .yui-gb div.first,.yui-gb .yui-gb div.first{*margin-right:0;*width:32%;_width:31.7%;}.yui-g .yui-gc div.first,.yui-gd .yui-g{width:66%;}.yui-gb .yui-g div.first{*margin-right:4%;_margin-right:1.3%;}.yui-gb .yui-gc div.first,.yui-gb .yui-gd div.first{*margin-right:0;}.yui-gb .yui-gb .yui-u,.yui-gb .yui-gc .yui-u{*margin-left:1.8%;_margin-left:4%;}.yui-g .yui-gb .yui-u{_margin-left:1.0%;}.yui-gb .yui-gd .yui-u{*width:66%;_width:61.2%;}.yui-gb .yui-gd div.first{*width:31%;_width:29.5%;}.yui-g .yui-gc .yui-u,.yui-gb .yui-gc .yui-u{width:32%;_float:right;margin-right:0;_margin-left:0;}.yui-gb .yui-gc div.first{width:66%;*float:left;*margin-left:0;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf .yui-u{margin:0;}.yui-gb .yui-gb .yui-u{_margin-left:.7%;}.yui-gb .yui-g div.first,.yui-gb .yui-gb div.first{*margin-left:0;}.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u{*width:48.1%;*margin-left:0;} .yui-gb .yui-gd div.first{width:32%;}.yui-g .yui-gd div.first{_width:29.9%;}.yui-ge .yui-g{width:24%;}.yui-gf .yui-g{width:74.2%;}.yui-gb .yui-ge div.yui-u,.yui-gb .yui-gf div.yui-u{float:right;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf div.first{float:left;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf div.first{*width:24%;_width:20%;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf .yui-u{*width:73.5%;_width:65.5%;}.yui-ge div.first .yui-gd .yui-u{width:65%;}.yui-ge div.first .yui-gd div.first{width:32%;}#bd:after,.yui-g:after,.yui-gb:after,.yui-gc:after,.yui-gd:after,.yui-ge:after,.yui-gf:after{content:".";display:block;height:0;clear:both;visibility:hidden;}#bd,.yui-g,.yui-gb,.yui-gc,.yui-gd,.yui-ge,.yui-gf{zoom:1;}
\ No newline at end of file +html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var,optgroup{font-style:inherit;font-weight:inherit;}del,ins{text-decoration:none;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:baseline;}sub{vertical-align:baseline;}legend{color:#000;}input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}input,button,textarea,select{*font-size:100%;}body{font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}select,input,button,textarea,button{font:99% arial,helvetica,clean,sans-serif;}table{font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}body{text-align:center;}#doc,#doc2,#doc3,#doc4,.yui-t1,.yui-t2,.yui-t3,.yui-t4,.yui-t5,.yui-t6,.yui-t7{margin:auto;text-align:left;width:57.69em;*width:56.25em;}#doc2{width:73.076em;*width:71.25em;}#doc3{margin:auto 10px;width:auto;}#doc4{width:74.923em;*width:73.05em;}.yui-b{position:relative;}.yui-b{_position:static;}#yui-main .yui-b{position:static;}#yui-main,.yui-g .yui-u .yui-g{width:100%;}.yui-t1 #yui-main,.yui-t2 #yui-main,.yui-t3 #yui-main{float:right;margin-left:-25em;}.yui-t4 #yui-main,.yui-t5 #yui-main,.yui-t6 #yui-main{float:left;margin-right:-25em;}.yui-t1 .yui-b{float:left;width:12.30769em;*width:12.00em;}.yui-t1 #yui-main .yui-b{margin-left:13.30769em;*margin-left:13.05em;}.yui-t2 .yui-b{float:left;width:13.8461em;*width:13.50em;}.yui-t2 #yui-main .yui-b{margin-left:14.8461em;*margin-left:14.55em;}.yui-t3 .yui-b{float:left;width:23.0769em;*width:22.50em;}.yui-t3 #yui-main .yui-b{margin-left:24.0769em;*margin-left:23.62em;}.yui-t4 .yui-b{float:right;width:13.8456em;*width:13.50em;}.yui-t4 #yui-main .yui-b{margin-right:14.8456em;*margin-right:14.55em;}.yui-t5 .yui-b{float:right;width:18.4615em;*width:18.00em;}.yui-t5 #yui-main .yui-b{margin-right:19.4615em;*margin-right:19.125em;}.yui-t6 .yui-b{float:right;width:23.0769em;*width:22.50em;}.yui-t6 #yui-main .yui-b{margin-right:24.0769em;*margin-right:23.62em;}.yui-t7 #yui-main .yui-b{display:block;margin:0 0 1em 0;}#yui-main .yui-b{float:none;width:auto;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf,.yui-gc .yui-u,.yui-gd .yui-g,.yui-g .yui-gc .yui-u,.yui-ge .yui-u,.yui-ge .yui-g,.yui-gf .yui-g,.yui-gf .yui-u{float:right;}.yui-g div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first,.yui-ge div.first,.yui-gf div.first,.yui-g .yui-gc div.first,.yui-g .yui-ge div.first,.yui-gc div.first div.first{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf{width:49.1%;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{width:32%;margin-left:1.99%;}.yui-gb .yui-u{*margin-left:1.9%;*width:31.9%;}.yui-gc div.first,.yui-gd .yui-u{width:66%;}.yui-gd div.first{width:32%;}.yui-ge div.first,.yui-gf .yui-u{width:74.2%;}.yui-ge .yui-u,.yui-gf div.first{width:24%;}.yui-g .yui-gb div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first{margin-left:0;}.yui-g .yui-g .yui-u,.yui-gb .yui-g .yui-u,.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u,.yui-ge .yui-g .yui-u,.yui-gf .yui-g .yui-u{width:49%;*width:48.1%;*margin-left:0;}.yui-g .yui-g .yui-u{width:48.1%;}.yui-g .yui-gb div.first,.yui-gb .yui-gb div.first{*margin-right:0;*width:32%;_width:31.7%;}.yui-g .yui-gc div.first,.yui-gd .yui-g{width:66%;}.yui-gb .yui-g div.first{*margin-right:4%;_margin-right:1.3%;}.yui-gb .yui-gc div.first,.yui-gb .yui-gd div.first{*margin-right:0;}.yui-gb .yui-gb .yui-u,.yui-gb .yui-gc .yui-u{*margin-left:1.8%;_margin-left:4%;}.yui-g .yui-gb .yui-u{_margin-left:1.0%;}.yui-gb .yui-gd .yui-u{*width:66%;_width:61.2%;}.yui-gb .yui-gd div.first{*width:31%;_width:29.5%;}.yui-g .yui-gc .yui-u,.yui-gb .yui-gc .yui-u{width:32%;_float:right;margin-right:0;_margin-left:0;}.yui-gb .yui-gc div.first{width:66%;*float:left;*margin-left:0;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf .yui-u{margin:0;}.yui-gb .yui-gb .yui-u{_margin-left:.7%;}.yui-gb .yui-g div.first,.yui-gb .yui-gb div.first{*margin-left:0;}.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u{*width:48.1%;*margin-left:0;}.yui-gb .yui-gd div.first{width:32%;}.yui-g .yui-gd div.first{_width:29.9%;}.yui-ge .yui-g{width:24%;}.yui-gf .yui-g{width:74.2%;}.yui-gb .yui-ge div.yui-u,.yui-gb .yui-gf div.yui-u{float:right;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf div.first{float:left;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf div.first{*width:24%;_width:20%;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf .yui-u{*width:73.5%;_width:65.5%;}.yui-ge div.first .yui-gd .yui-u{width:65%;}.yui-ge div.first .yui-gd div.first{width:32%;}#hd:after,#bd:after,#ft:after,.yui-g:after,.yui-gb:after,.yui-gc:after,.yui-gd:after,.yui-ge:after,.yui-gf:after{content:".";display:block;height:0;clear:both;visibility:hidden;}#hd,#bd,#ft,.yui-g,.yui-gb,.yui-gc,.yui-gd,.yui-ge,.yui-gf{zoom:1;}
\ No newline at end of file diff --git a/modules/akismet/controllers/admin_akismet.php b/modules/akismet/controllers/admin_akismet.php index 8d292cf4..af98536a 100644 --- a/modules/akismet/controllers/admin_akismet.php +++ b/modules/akismet/controllers/admin_akismet.php @@ -50,6 +50,7 @@ class Admin_Akismet_Controller extends Admin_Controller { akismet::check_config(); $view = new Admin_View("admin.html"); + $view->page_title = t("Akismet spam filtering"); $view->content = new View("admin_akismet.html"); $view->content->valid_key = $valid_key; $view->content->form = $form; diff --git a/modules/comment/controllers/admin_comments.php b/modules/comment/controllers/admin_comments.php index 3abfe1de..68794638 100644 --- a/modules/comment/controllers/admin_comments.php +++ b/modules/comment/controllers/admin_comments.php @@ -44,6 +44,7 @@ class Admin_Comments_Controller extends Admin_Controller { $page = max(Input::instance()->get("page"), 1); $view = new Admin_View("admin.html"); + $view->page_title = t("Manage comments"); $view->content = new View("admin_comments.html"); $view->content->counts = $this->_counts(); $view->content->menu = $this->_menu($view->content->counts); diff --git a/modules/comment/css/comment.css b/modules/comment/css/comment.css index f58391b0..db096f2d 100644 --- a/modules/comment/css/comment.css +++ b/modules/comment/css/comment.css @@ -28,7 +28,7 @@ width: 32px; } -#g-admin-comment-button { +#g-add-comment { position: absolute; right: 0; top: 2px; diff --git a/modules/comment/js/comment.js b/modules/comment/js/comment.js index 3c8097c6..2487c5fc 100644 --- a/modules/comment/js/comment.js +++ b/modules/comment/js/comment.js @@ -1,5 +1,5 @@ $("document").ready(function() { - $("#g-admin-comment-button").click(function(event) { + $("#g-add-comment").click(function(event) { event.preventDefault(); if (!$("#g-comment-form").length) { $.get($(this).attr("href"), @@ -7,10 +7,11 @@ $("document").ready(function() { function(data) { $("#g-comment-detail").append(data); ajaxify_comment_form(); + $.scrollTo("#g-comment-form-anchor", 800); }); } }); - $("#g-no-comments").click(function(event) { + $(".g-no-comments a").click(function(event) { event.preventDefault(); if (!$("#g-comment-form").length) { $.get($(this).attr("href"), @@ -19,7 +20,7 @@ $("document").ready(function() { $("#g-comment-detail").append(data); ajaxify_comment_form(); }); - $("#g-no-comments-yet").remove(); + $(".g-no-comments").remove(); } }); }); @@ -32,7 +33,7 @@ function ajaxify_comment_form() { $("#g-comments #g-comment-detail ul").append(data.view); $("#g-comments #g-comment-detail ul li:last").effect("highlight", {color: "#cfc"}, 8000); $("#g-comment-form").hide(2000).remove(); - $("#g-no-comments-yet").hide(2000); + $("#g-no-comments").hide(2000); } else { if (data.form) { $("#g-comments form").replaceWith(data.form); diff --git a/modules/comment/views/comments.html.php b/modules/comment/views/comments.html.php index 8e2a9e51..e4322e08 100644 --- a/modules/comment/views/comments.html.php +++ b/modules/comment/views/comments.html.php @@ -1,45 +1,46 @@ <?php defined("SYSPATH") or die("No direct script access.") ?> - <a href="<?= url::site("form/add/comments/{$item->id}") ?>" id="g-admin-comment-button" + <a href="<?= url::site("form/add/comments/{$item->id}") ?>#comment-form" id="g-add-comment" class="g-button ui-corner-all ui-icon-left ui-state-default"> <span class="ui-icon ui-icon-comment"></span> <?= t("Add a comment") ?> </a> <div id="g-comment-detail"> -<? if (!$comments->count()): ?> -<p id="g-no-comments-yet"> - <?= t("No comments yet. Be the first to <a %attrs>comment</a>!", - array("attrs" => html::mark_clean("id= \"g-no-comments\" href=\"" . url::site("form/add/comments/{$item->id}") . "\" class=\"showCommentForm\""))) ?> -</p> -<ul> </ul> -<? endif ?> -<? if ($comments->count()): ?> -<ul> - <? foreach ($comments as $comment): ?> - <li id="g-comment-<?= $comment->id ?>"> - <p class="g-author"> - <a href="#"> - <img src="<?= $comment->author()->avatar_url(40, $theme->url("images/avatar.jpg", true)) ?>" - class="g-avatar" - alt="<?= html::clean_attribute($comment->author_name()) ?>" - width="40" - height="40" /> - </a> - <? if ($comment->author()->guest): ?> - <?= t('on %date %name said', - array("date" => date("Y-M-d H:i:s", $comment->created), - "name" => html::clean($comment->author_name()))); ?> - <? else: ?> - <?= t('on %date <a href="%url">%name</a> said', - array("date" => date("Y-M-d H:i:s", $comment->created), - "url" => user_profile::url($comment->author_id), - "name" => html::clean($comment->author_name()))); ?> - <? endif ?> - </p> - <div> - <?= nl2br(html::purify($comment->text)) ?> - </div> - </li> - <? endforeach ?> -</ul> -<? endif ?> + <? if (!$comments->count()): ?> + <p class="g-no-comments"> + <?= t("No comments yet. Be the first to <a %attrs>comment</a>!", + array("attrs" => html::mark_clean("href=\"" . url::site("form/add/comments/{$item->id}") . "\" class=\"showCommentForm\""))) ?> + </p> + <ul><li class="g-no-comments"> </li></ul> + <? endif ?> + <? if ($comments->count()): ?> + <ul> + <? foreach ($comments as $comment): ?> + <li id="g-comment-<?= $comment->id ?>"> + <p class="g-author"> + <a href="#"> + <img src="<?= $comment->author()->avatar_url(40, $theme->url("images/avatar.jpg", true)) ?>" + class="g-avatar" + alt="<?= html::clean_attribute($comment->author_name()) ?>" + width="40" + height="40" /> + </a> + <? if ($comment->author()->guest): ?> + <?= t('on %date %name said', + array("date" => date("Y-M-d H:i:s", $comment->created), + "name" => html::clean($comment->author_name()))); ?> + <? else: ?> + <?= t('on %date <a href="%url">%name</a> said', + array("date" => date("Y-M-d H:i:s", $comment->created), + "url" => user_profile::url($comment->author_id), + "name" => html::clean($comment->author_name()))); ?> + <? endif ?> + </p> + <div> + <?= nl2br(html::purify($comment->text)) ?> + </div> + </li> + <? endforeach ?> + </ul> + <? endif ?> + <a name="comment-form" id="g-comment-form-anchor"></a> </div> diff --git a/modules/digibug/controllers/admin_digibug.php b/modules/digibug/controllers/admin_digibug.php index 76ed2319..f3a0f8f0 100644 --- a/modules/digibug/controllers/admin_digibug.php +++ b/modules/digibug/controllers/admin_digibug.php @@ -20,6 +20,7 @@ class Admin_Digibug_Controller extends Admin_Controller { public function index() { $v = new Admin_View("admin.html"); + $v->page_title = t("Digibug"); $v->content = new View("admin_digibug.html"); print $v; } diff --git a/modules/digibug/views/admin_digibug.html.php b/modules/digibug/views/admin_digibug.html.php index 5d07eb68..d673b116 100644 --- a/modules/digibug/views/admin_digibug.html.php +++ b/modules/digibug/views/admin_digibug.html.php @@ -1,7 +1,7 @@ <?php defined("SYSPATH") or die("No direct script access.") ?> <div class="g-block"> <img src="<?= url::file("modules/digibug/images/digibug_logo.png") ?>" alt="Digibug logo" class="g-right"/> - <h1> <?= t("Digibug Photo Printing") ?> </h1> + <h1> <?= t("Digibug photo printing") ?> </h1> <div class="g-block-content"> <p> <?= t("Turn your photos into a wide variety of prints, gifts and games!") ?> diff --git a/modules/g2_import/controllers/admin_g2_import.php b/modules/g2_import/controllers/admin_g2_import.php index bc00378d..b1018560 100644 --- a/modules/g2_import/controllers/admin_g2_import.php +++ b/modules/g2_import/controllers/admin_g2_import.php @@ -30,6 +30,7 @@ class Admin_g2_import_Controller extends Admin_Controller { } $view = new Admin_View("admin.html"); + $view->page_title = t("Gallery 2 import"); $view->content = new View("admin_g2_import.html"); $view->content->form = $this->_get_import_form(); $view->content->version = ''; diff --git a/modules/g2_import/helpers/g2_import.php b/modules/g2_import/helpers/g2_import.php index 9c20ec4d..575d02bb 100644 --- a/modules/g2_import/helpers/g2_import.php +++ b/modules/g2_import/helpers/g2_import.php @@ -265,7 +265,7 @@ class g2_import_Core { $e); } } - + break; case GROUP_ALL_USERS: @@ -587,6 +587,7 @@ class g2_import_Core { if (in_array($g2_item->getMimeType(), array("video/mp4", "video/x-flv"))) { try { $item = ORM::factory("item"); + $item->type = "movie"; $item->parent_id = $parent->id; $item->set_data_file($g2_path); $item->name = $g2_item->getPathComponent(); @@ -1202,23 +1203,3 @@ function g2() { return $args; } } - -/** - * A wrapper for exceptions to report more details in case - * it's a ORM validation exception. - */ -class G2_Import_Exception extends Exception { - public function __construct($message, Exception $previous=null, $additional_messages=null) { - if ($additional_messages) { - $message .= "\n" . implode("\n", $additional_messages); - } - if ($previous && $previous instanceof ORM_Validation_Exception) { - $message .= "\nORM validation errors: " . print_r($previous->validation->errors(), true); - } - if ($previous) { - $message .= "\n" . (string) $previous; - } - // The $previous parameter is supported in PHP 5.3.0+. - parent::__construct($message); - } -}
\ No newline at end of file diff --git a/modules/g2_import/libraries/G2_Import_Exception.php b/modules/g2_import/libraries/G2_Import_Exception.php new file mode 100644 index 00000000..591f51cd --- /dev/null +++ b/modules/g2_import/libraries/G2_Import_Exception.php @@ -0,0 +1,39 @@ +<?php defined("SYSPATH") or die("No direct script access."); +/** + * Gallery - a web based photo album viewer and editor + * Copyright (C) 2000-2010 Bharat Mediratta + * + * 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. + */ + +/** + * A wrapper for exceptions to report more details in case + * it's a ORM validation exception. + */ +class G2_Import_Exception extends Exception { + public function __construct($message, Exception $previous=null, $additional_messages=null) { + if ($additional_messages) { + $message .= "\n" . implode("\n", $additional_messages); + } + if ($previous && $previous instanceof ORM_Validation_Exception) { + $message .= "\nORM validation errors: " . print_r($previous->validation->errors(), true); + } + if ($previous) { + $message .= "\n" . (string) $previous; + } + // The $previous parameter is supported in PHP 5.3.0+. + parent::__construct($message); + } +}
\ No newline at end of file diff --git a/modules/gallery/controllers/admin_advanced_settings.php b/modules/gallery/controllers/admin_advanced_settings.php index d9a281b5..6f4e9403 100644 --- a/modules/gallery/controllers/admin_advanced_settings.php +++ b/modules/gallery/controllers/admin_advanced_settings.php @@ -20,6 +20,7 @@ class Admin_Advanced_Settings_Controller extends Admin_Controller { public function index() { $view = new Admin_View("admin.html"); + $view->page_title = t("Advanced settings"); $view->content = new View("admin_advanced_settings.html"); $view->content->vars = ORM::factory("var") ->order_by("module_name") diff --git a/modules/gallery/controllers/admin_dashboard.php b/modules/gallery/controllers/admin_dashboard.php index adc0df16..76c42612 100644 --- a/modules/gallery/controllers/admin_dashboard.php +++ b/modules/gallery/controllers/admin_dashboard.php @@ -20,6 +20,7 @@ class Admin_Dashboard_Controller extends Admin_Controller { public function index() { $view = new Admin_View("admin.html"); + $view->page_title = t("Dashboard"); $view->content = new View("admin_dashboard.html"); $view->content->blocks = block_manager::get_html("dashboard_center"); $view->sidebar = "<div id=\"g-admin-dashboard-sidebar\">" . diff --git a/modules/gallery/controllers/admin_graphics.php b/modules/gallery/controllers/admin_graphics.php index abbd8986..de98035d 100644 --- a/modules/gallery/controllers/admin_graphics.php +++ b/modules/gallery/controllers/admin_graphics.php @@ -20,6 +20,7 @@ class Admin_Graphics_Controller extends Admin_Controller { public function index() { $view = new Admin_View("admin.html"); + $view->page_title = t("Graphics settings"); $view->content = new View("admin_graphics.html"); $view->content->tk = graphics::detect_toolkits(); $view->content->active = module::get_var("gallery", "graphics_toolkit", "none"); diff --git a/modules/gallery/controllers/admin_languages.php b/modules/gallery/controllers/admin_languages.php index 1ca777dc..0f134fcd 100644 --- a/modules/gallery/controllers/admin_languages.php +++ b/modules/gallery/controllers/admin_languages.php @@ -20,6 +20,7 @@ class Admin_Languages_Controller extends Admin_Controller { public function index($share_translations_form=null) { $v = new Admin_View("admin.html"); + $v->page_title = t("Languages and translations"); $v->content = new View("admin_languages.html"); $v->content->available_locales = locales::available(); $v->content->installed_locales = locales::installed(); diff --git a/modules/gallery/controllers/admin_modules.php b/modules/gallery/controllers/admin_modules.php index 30e1ace5..bf638a37 100644 --- a/modules/gallery/controllers/admin_modules.php +++ b/modules/gallery/controllers/admin_modules.php @@ -20,6 +20,7 @@ class Admin_Modules_Controller extends Admin_Controller { public function index() { $view = new Admin_View("admin.html"); + $view->page_title = t("Modules"); $view->content = new View("admin_modules.html"); $view->content->available = module::available(); print $view; diff --git a/modules/gallery/controllers/admin_sidebar.php b/modules/gallery/controllers/admin_sidebar.php index 73f84d2f..fb857e4e 100644 --- a/modules/gallery/controllers/admin_sidebar.php +++ b/modules/gallery/controllers/admin_sidebar.php @@ -20,6 +20,7 @@ class Admin_Sidebar_Controller extends Admin_Controller { public function index() { $view = new Admin_View("admin.html"); + $view->page_title = t("Manage sidebar"); $view->content = new View("admin_sidebar.html"); $view->content->csrf = access::csrf_token(); $view->content->available = new View("admin_sidebar_blocks.html"); diff --git a/modules/gallery/controllers/admin_theme_options.php b/modules/gallery/controllers/admin_theme_options.php index cf4fb77a..15a42ee5 100644 --- a/modules/gallery/controllers/admin_theme_options.php +++ b/modules/gallery/controllers/admin_theme_options.php @@ -20,6 +20,7 @@ class Admin_Theme_Options_Controller extends Admin_Controller { public function index() { $view = new Admin_View("admin.html"); + $view->page_title = t("Theme options"); $view->content = new View("admin_theme_options.html"); $view->content->form = theme::get_edit_form_admin(); print $view; diff --git a/modules/gallery/controllers/admin_themes.php b/modules/gallery/controllers/admin_themes.php index 327ea6c8..e59eadaf 100644 --- a/modules/gallery/controllers/admin_themes.php +++ b/modules/gallery/controllers/admin_themes.php @@ -20,6 +20,7 @@ class Admin_Themes_Controller extends Admin_Controller { public function index() { $view = new Admin_View("admin.html"); + $view->page_title = t("Theme choice"); $view->content = new View("admin_themes.html"); $view->content->admin = module::get_var("gallery", "active_admin_theme"); $view->content->site = module::get_var("gallery", "active_site_theme"); diff --git a/modules/gallery/controllers/albums.php b/modules/gallery/controllers/albums.php index 730db9ae..ea15418f 100644 --- a/modules/gallery/controllers/albums.php +++ b/modules/gallery/controllers/albums.php @@ -107,6 +107,7 @@ class Albums_Controller extends Items_Controller { if ($valid) { $album->save(); + module::event("album_add_form_completed", $album, $form); log::success("content", "Created an album", html::anchor("albums/$album->id", "view album")); message::success(t("Created album %album_title", diff --git a/modules/gallery/controllers/reauthenticate.php b/modules/gallery/controllers/reauthenticate.php index b2a67f01..3503d80a 100644 --- a/modules/gallery/controllers/reauthenticate.php +++ b/modules/gallery/controllers/reauthenticate.php @@ -63,7 +63,7 @@ class Reauthenticate_Controller extends Controller { $group->password("password")->label(t("Password"))->id("g-password")->class(null) ->callback("auth::validate_too_many_failed_auth_attempts") ->callback("user::valid_password") - ->error_messages("invalid", t("Incorrect password")) + ->error_messages("invalid_password", t("Incorrect password")) ->error_messages( "too_many_failed_auth_attempts", t("Too many incorrect passwords. Try again later")); diff --git a/modules/gallery/helpers/album.php b/modules/gallery/helpers/album.php index 521806a0..0baae631 100644 --- a/modules/gallery/helpers/album.php +++ b/modules/gallery/helpers/album.php @@ -45,9 +45,13 @@ class album_Core { ->error_messages("required", t("You must provide an internet address")) ->error_messages("length", t("Your internet address is too long")); $group->hidden("type")->value("album"); + + module::event("album_add_form", $parent, $form); + $group->submit("")->value(t("Create")); $form->script("") ->url(url::abs_file("modules/gallery/js/albums_form_add.js")); + return $form; } diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index d723cc1b..2416f2e5 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -97,6 +97,17 @@ class gallery_event_Core { static function item_deleted($item) { access::delete_item($item); + + $parent = $item->parent(); + if (!$parent->album_cover_item_id) { + // Assume we deleted the album cover and pick a new one. Choosing the first photo in the + // album is logical, but it's not the most efficient in the case where we're deleting all + // the photos in the album one at a time since we'll probably delete them in order which + // means that we'll be resetting the album cover each time. + if ($child = $parent->children(1)->current()) { + item::make_album_cover($child); + } + } } static function item_moved($item, $old_parent) { diff --git a/modules/gallery/helpers/gallery_task.php b/modules/gallery/helpers/gallery_task.php index fa95c612..bc128b3e 100644 --- a/modules/gallery/helpers/gallery_task.php +++ b/modules/gallery/helpers/gallery_task.php @@ -18,6 +18,9 @@ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ class gallery_task_Core { + const MPTT_LEFT = 0; + const MPTT_RIGHT = 1; + static function available_tasks() { $dirty_count = graphics::find_dirty_images_query()->count_records(); $tasks = array(); @@ -42,6 +45,14 @@ class gallery_task_Core { ->name(t("Remove old files")) ->description(t("Remove expired files from the logs and tmp directory")) ->severity(log::SUCCESS); + + $tasks[] = Task_Definition::factory() + ->callback("gallery_task::fix_mptt") + ->name(t("Fix Album/Photo hierarchy")) + ->description(t("Fix problems where your album/photo breadcrumbs are out of " . + "sync with your actual hierarchy.")) + ->severity(log::SUCCESS); + return $tasks; } @@ -298,4 +309,79 @@ class gallery_task_Core { $task->log($errors); } } + + static function fix_mptt($task) { + $start = microtime(true); + + $total = $task->get("total"); + if (empty($total)) { + $task->set("total", $total = db::build()->count_records("items")); + $task->set("stack", "1:" . self::MPTT_LEFT); + $task->set("ptr", 1); + $task->set("completed", 0); + } + + $ptr = $task->get("ptr"); + $stack = explode(" ", $task->get("stack")); + $completed = $task->get("completed"); + + // Implement a depth-first tree walk using a stack. Not the most efficient, but it's simple. + while ($stack && microtime(true) - $start < 1.5) { + list($id, $state) = explode(":", array_pop($stack)); + switch ($state) { + case self::MPTT_LEFT: + self::fix_mptt_set_left($id, $ptr++); + $item = ORM::factory("item", $id); + array_push($stack, $id . ":" . self::MPTT_RIGHT); + foreach (self::fix_mptt_children($id) as $child) { + array_push($stack, $child->id . ":" . self::MPTT_LEFT); + } + break; + + case self::MPTT_RIGHT: + self::fix_mptt_set_right($id, $ptr++); + $completed++; + break; + } + } + + $task->set("stack", implode(" ", $stack)); + $task->set("ptr", $ptr); + $task->set("completed", $completed); + + if ($total == $completed) { + $task->done = true; + $task->state = "success"; + $task->percent_complete = 100; + } else { + $task->percent_complete = round(100 * $completed / $total); + } + $task->status = t2("One row updated", "%count / %total rows updated", $completed, + array("total" => $total)); + } + + static function fix_mptt_children($parent_id) { + return db::build() + ->select("id") + ->from("items") + ->where("parent_id", "=", $parent_id) + ->order_by("left_ptr", "ASC") + ->execute(); + } + + static function fix_mptt_set_left($id, $value) { + db::build() + ->update("items") + ->set("left_ptr", $value) + ->where("id", "=", $id) + ->execute(); + } + + static function fix_mptt_set_right($id, $value) { + db::build() + ->update("items") + ->set("right_ptr", $value) + ->where("id", "=", $id) + ->execute(); + } }
\ No newline at end of file diff --git a/modules/gallery/helpers/item_rest.php b/modules/gallery/helpers/item_rest.php index 16abec5a..36d2ca62 100644 --- a/modules/gallery/helpers/item_rest.php +++ b/modules/gallery/helpers/item_rest.php @@ -70,49 +70,70 @@ class item_rest_Core { $orm->where("type", "IN", explode(",", $p->type)); } - $members = array(); - foreach ($orm->find_all() as $child) { - $members[] = rest::url("item", $child); + // Apply the item's sort order, using id as the tie breaker. + // See Item_Model::children() + $order_by = array($item->sort_column => $item->sort_order); + if ($item->sort_column != "id") { + $order_by["id"] = "ASC"; } + $orm->order_by($order_by); - return array( + $result = array( "url" => $request->url, "entity" => $item->as_restful_array(), - "members" => $members, "relationships" => rest::relationships("item", $item)); + if ($item->is_album()) { + $result["members"] = array(); + foreach ($orm->find_all() as $child) { + $result["members"][] = rest::url("item", $child); + } + } + + return $result; } static function put($request) { $item = rest::resolve($request->url); access::required("edit", $item); - $params = $request->params; - - // Only change fields from a whitelist. - foreach (array("album_cover", "captured", "description", - "height", "mime_type", "name", "parent", "rand_key", "resize_dirty", - "resize_height", "resize_width", "slug", "sort_column", "sort_order", - "thumb_dirty", "thumb_height", "thumb_width", "title", "view_count", - "weight", "width") as $key) { - switch ($key) { - case "album_cover": - if (property_exists($request->params, "album_cover")) { - $album_cover_item = rest::resolve($request->params->album_cover); - access::required("view", $album_cover_item); - $item->album_cover_item_id = $album_cover_item->id; + if ($entity = $request->params->entity) { + // Only change fields from a whitelist. + foreach (array("album_cover", "captured", "description", + "height", "mime_type", "name", "parent", "rand_key", "resize_dirty", + "resize_height", "resize_width", "slug", "sort_column", "sort_order", + "thumb_dirty", "thumb_height", "thumb_width", "title", "view_count", + "width") as $key) { + switch ($key) { + case "album_cover": + if (property_exists($entity, "album_cover")) { + $album_cover_item = rest::resolve($entity->album_cover); + access::required("view", $album_cover_item); + $item->album_cover_item_id = $album_cover_item->id; + } + break; + + case "parent": + if (property_exists($entity, "parent")) { + $parent = rest::resolve($entity->parent); + access::required("edit", $parent); + $item->parent_id = $parent->id; + } + break; + default: + if (property_exists($entity, $key)) { + $item->$key = $entity->$key; + } } - break; + } + } - case "parent": - if (property_exists($request->params, "parent")) { - $parent = rest::resolve($request->params->parent); - access::required("edit", $parent); - $item->parent_id = $parent->id; - } - break; - default: - if (property_exists($request->params, $key)) { - $item->$key = $request->params->$key; + $weight = 0; + if (isset($request->params->members)) { + foreach ($request->params->members as $url) { + $child = rest::resolve($url); + if ($child->parent_id == $item->id && $child->weight != $weight) { + $child->weight = $weight++; + $child->save(); } } } @@ -123,33 +144,33 @@ class item_rest_Core { $parent = rest::resolve($request->url); access::required("edit", $parent); - $params = $request->params; + $entity = $request->params->entity; $item = ORM::factory("item"); - switch ($params->type) { + switch ($entity->type) { case "album": $item->type = "album"; $item->parent_id = $parent->id; - $item->name = $params->name; - $item->title = isset($params->title) ? $params->title : $name; - $item->description = isset($params->description) ? $params->description : null; - $item->slug = isset($params->slug) ? $params->slug : null; + $item->name = $entity->name; + $item->title = isset($entity->title) ? $entity->title : $name; + $item->description = isset($entity->description) ? $entity->description : null; + $item->slug = isset($entity->slug) ? $entity->slug : null; $item->save(); break; case "photo": case "movie": - $item->type = $params->type; + $item->type = $entity->type; $item->parent_id = $parent->id; $item->set_data_file($request->file); - $item->name = $params->name; - $item->title = isset($params->title) ? $params->title : $params->name; - $item->description = isset($params->description) ? $params->description : null; - $item->slug = isset($params->slug) ? $params->slug : null; + $item->name = $entity->name; + $item->title = isset($entity->title) ? $entity->title : $entity->name; + $item->description = isset($entity->description) ? $entity->description : null; + $item->slug = isset($entity->slug) ? $entity->slug : null; $item->save(); break; default: - throw new Rest_Exception("Invalid type: $params->type", 400); + throw new Rest_Exception("Invalid type: $entity->type", 400); } return array("url" => rest::url("item", $item)); diff --git a/modules/gallery/helpers/items_rest.php b/modules/gallery/helpers/items_rest.php index 05ca65cf..5d8e80b2 100644 --- a/modules/gallery/helpers/items_rest.php +++ b/modules/gallery/helpers/items_rest.php @@ -22,19 +22,20 @@ class items_rest_Core { $items = array(); if (isset($request->params->url)) { - foreach($request->params->url as $url) { + foreach (json_decode($request->params->url) as $url) { $item = rest::resolve($url); if (access::can("view", $item)) { - $members = array(); + $item_rest = array("url" => $url, + "entity" => $item->as_restful_array(), + "relationship" => rest::relationships("item", $item)); if ($item->type == "album") { + $members = array(); foreach ($item->children() as $child) { $members[] = rest::url("item", $child); } + $item_rest["members"] = $members; } - $items[] = array("url" => $url, - "entity" => $item->as_restful_array(), - "members" => $members, - "relationship" => rest::relationships("item", $item)); + $items[] = $item_rest; } } } diff --git a/modules/gallery/helpers/theme.php b/modules/gallery/helpers/theme.php index ae5f030c..980ee11a 100644 --- a/modules/gallery/helpers/theme.php +++ b/modules/gallery/helpers/theme.php @@ -73,12 +73,18 @@ class theme_Core { $group = $form->group("edit_theme"); $group->input("page_size")->label(t("Items per page"))->id("g-page-size") ->rules("required|valid_digit") + ->error_messages("required", t("You must enter a number")) + ->error_messages("valid_digit", t("You must enter a number")) ->value(module::get_var("gallery", "page_size")); $group->input("thumb_size")->label(t("Thumbnail size (in pixels)"))->id("g-thumb-size") ->rules("required|valid_digit") + ->error_messages("required", t("You must enter a number")) + ->error_messages("valid_digit", t("You must enter a number")) ->value(module::get_var("gallery", "thumb_size")); $group->input("resize_size")->label(t("Resized image size (in pixels)"))->id("g-resize-size") ->rules("required|valid_digit") + ->error_messages("required", t("You must enter a number")) + ->error_messages("valid_digit", t("You must enter a number")) ->value(module::get_var("gallery", "resize_size")); $group->textarea("header_text")->label(t("Header text"))->id("g-header-text") ->value(module::get_var("gallery", "header_text")); diff --git a/modules/gallery/libraries/MY_Input.php b/modules/gallery/libraries/MY_Input.php index 703136c7..1d5949e8 100644 --- a/modules/gallery/libraries/MY_Input.php +++ b/modules/gallery/libraries/MY_Input.php @@ -26,6 +26,6 @@ class Input extends Input_Core { * @return string */ public function clean_input_keys($str) { - return preg_replace('#^[\pL0-9:_.-]++$#uD', '_', $str); + return preg_replace('#[^a-zA-Z0-9:_.-]+#', '_', $str); } } diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php index 6ede5109..7fc37325 100644 --- a/modules/gallery/models/item.php +++ b/modules/gallery/models/item.php @@ -332,6 +332,12 @@ class Item_Model extends ORM_MPTT { $tmp = pathinfo($this->name, PATHINFO_FILENAME); $tmp = preg_replace("/[^A-Za-z0-9-_]+/", "-", $tmp); $this->slug = trim($tmp, "-"); + + // If the filename is all invalid characters, then the slug may be empty here. Pick a + // random value. + if (empty($this->slug)) { + $this->slug = (string)rand(1000, 9999); + } } // Get the width, height and mime type from our data file for photos and movies. @@ -941,7 +947,7 @@ class Item_Model extends ORM_MPTT { // Elide some internal-only data that is going to cause confusion in the client. foreach (array("relative_path_cache", "relative_url_cache", "left_ptr", "right_ptr", - "thumb_dirty", "resize_dirty") as $key) { + "thumb_dirty", "resize_dirty", "weight") as $key) { unset($data[$key]); } return $data; diff --git a/modules/gallery/tests/Input_Library_Test.php b/modules/gallery/tests/Input_Library_Test.php new file mode 100644 index 00000000..06641323 --- /dev/null +++ b/modules/gallery/tests/Input_Library_Test.php @@ -0,0 +1,25 @@ +<?php defined("SYSPATH") or die("No direct script access."); +/** + * Gallery - a web based photo album viewer and editor + * Copyright (C) 2000-2010 Bharat Mediratta + * + * 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. + */ +class Input_Library_Test extends Gallery_Unit_Test_Case { + function clean_input_keys_test() { + $input = Input::instance(); + $this->assert_same("foo_bar", $input->clean_input_keys("foo|bar")); + } +}
\ No newline at end of file diff --git a/modules/gallery/tests/Item_Helper_Test.php b/modules/gallery/tests/Item_Helper_Test.php index 295871a5..4771b11a 100644 --- a/modules/gallery/tests/Item_Helper_Test.php +++ b/modules/gallery/tests/Item_Helper_Test.php @@ -54,7 +54,6 @@ class Item_Helper_Test extends Gallery_Unit_Test_Case { $this->assert_same($dst_album->id, $photo->parent_id); } - public function move_updates_album_covers_test() { // 2 photos in the source album $src_album = test::random_album(); @@ -106,4 +105,16 @@ class Item_Helper_Test extends Gallery_Unit_Test_Case { $this->assert_not_same("{$rand}.jpg", $photo2->name); $this->assert_not_same($rand, $photo2->slug); } + + public function delete_cover_photo_picks_new_album_cover() { + $album = test::random_album(); + $photo1 = test::random_photo($album); + // At this point, $photo1 is the album cover. We verify this in + // Item_Model_Test::first_photo_becomes_album_cover + $photo2 = test::random_photo($album); + $photo1->delete(); + $album->reload(); + + $this->assert_same($photo2->id, $album->album_cover_item_id); + } } diff --git a/modules/gallery/tests/Item_Model_Test.php b/modules/gallery/tests/Item_Model_Test.php index d0676292..15aa2d8c 100644 --- a/modules/gallery/tests/Item_Model_Test.php +++ b/modules/gallery/tests/Item_Model_Test.php @@ -295,7 +295,6 @@ class Item_Model_Test extends Gallery_Unit_Test_Case { } catch (ORM_Validation_Exception $e) { $this->assert_same(array("description" => "length", "name" => "required", - "slug" => "required", "title" => "required", "album_cover_item_id" => "invalid_item", "parent_id" => "invalid", @@ -324,6 +323,12 @@ class Item_Model_Test extends Gallery_Unit_Test_Case { $album->save(); } + public function name_with_only_invalid_chars_is_still_valid_test() { + $album = test::random_album_unsaved(); + $album->name = "[]"; + $album->save(); + } + public function cant_change_item_type_test() { $photo = test::random_photo(); try { @@ -358,4 +363,12 @@ class Item_Model_Test extends Gallery_Unit_Test_Case { $this->assert_true(!array_key_exists("parent_id", $result)); $this->assert_true(!array_key_exists("album_cover_item_id", $result)); } + + public function first_photo_becomes_album_cover() { + $album = test::random_album(); + $photo = test::random_photo($album); + $album->reload(); + + $this->assert_same($photo->id, $album->album_cover_item_id); + } } diff --git a/modules/gallery/tests/Item_Rest_Helper_Test.php b/modules/gallery/tests/Item_Rest_Helper_Test.php index bef95668..0b5e0471 100644 --- a/modules/gallery/tests/Item_Rest_Helper_Test.php +++ b/modules/gallery/tests/Item_Rest_Helper_Test.php @@ -42,13 +42,14 @@ class Item_Rest_Helper_Test extends Gallery_Unit_Test_Case { $this->assert_equal_array( array("url" => rest::url("item", $album1), "entity" => $album1->as_restful_array(), - "members" => array( - rest::url("item", $photo1), - rest::url("item", $album2)), "relationships" => array( "tags" => array( "url" => rest::url("item_tags", $album1), - "members" => array()))), + "members" => array())), + "members" => array( + rest::url("item", $photo1), + rest::url("item", $album2)), + ), item_rest::get($request)); $request->url = rest::url("item", $album1); @@ -56,13 +57,14 @@ class Item_Rest_Helper_Test extends Gallery_Unit_Test_Case { $this->assert_equal_array( array("url" => rest::url("item", $album1), "entity" => $album1->as_restful_array(), - "members" => array( - rest::url("item", $photo1), - rest::url("item", $album2)), "relationships" => array( "tags" => array( "url" => rest::url("item_tags", $album1), - "members" => array()))), + "members" => array())), + "members" => array( + rest::url("item", $photo1), + rest::url("item", $album2)), + ), item_rest::get($request)); $request->url = rest::url("item", $album1); @@ -70,14 +72,15 @@ class Item_Rest_Helper_Test extends Gallery_Unit_Test_Case { $this->assert_equal_array( array("url" => rest::url("item", $album1), "entity" => $album1->as_restful_array(), + "relationships" => array( + "tags" => array( + "url" => rest::url("item_tags", $album1), + "members" => array())), "members" => array( rest::url("item", $photo1), rest::url("item", $album2), rest::url("item", $photo2)), - "relationships" => array( - "tags" => array( - "url" => rest::url("item_tags", $album1), - "members" => array()))), + ), item_rest::get($request)); } @@ -96,12 +99,13 @@ class Item_Rest_Helper_Test extends Gallery_Unit_Test_Case { $this->assert_equal_array( array("url" => rest::url("item", $album1), "entity" => $album1->as_restful_array(), - "members" => array( - rest::url("item", $photo2)), "relationships" => array( "tags" => array( "url" => rest::url("item_tags", $album1), - "members" => array()))), + "members" => array())), + "members" => array( + rest::url("item", $photo2)), + ), item_rest::get($request)); } @@ -118,12 +122,13 @@ class Item_Rest_Helper_Test extends Gallery_Unit_Test_Case { $this->assert_equal_array( array("url" => rest::url("item", $album1), "entity" => $album1->as_restful_array(), - "members" => array( - rest::url("item", $album2)), "relationships" => array( "tags" => array( "url" => rest::url("item_tags", $album1), - "members" => array() ))), + "members" => array())), + "members" => array( + rest::url("item", $album2)), + ), item_rest::get($request)); } @@ -134,7 +139,8 @@ class Item_Rest_Helper_Test extends Gallery_Unit_Test_Case { $request = new stdClass(); $request->url = rest::url("item", $album1); $request->params = new stdClass(); - $request->params->title = "my new title"; + $request->params->entity = new stdClass(); + $request->params->entity->title = "my new title"; item_rest::put($request); $this->assert_equal("my new title", $album1->reload()->title); @@ -147,8 +153,9 @@ class Item_Rest_Helper_Test extends Gallery_Unit_Test_Case { $request = new stdClass(); $request->url = rest::url("item", $album1); $request->params = new stdClass(); - $request->params->title = "my new title"; - $request->params->slug = "not url safe"; + $request->params->entity = new stdClass(); + $request->params->entity->title = "my new title"; + $request->params->entity->slug = "not url safe"; try { item_rest::put($request); @@ -166,9 +173,10 @@ class Item_Rest_Helper_Test extends Gallery_Unit_Test_Case { $request = new stdClass(); $request->url = rest::url("item", $album1); $request->params = new stdClass(); - $request->params->type = "album"; - $request->params->name = "my album"; - $request->params->title = "my album"; + $request->params->entity = new stdClass(); + $request->params->entity->type = "album"; + $request->params->entity->name = "my album"; + $request->params->entity->title = "my album"; $response = item_rest::post($request); $new_album = rest::resolve($response["url"]); @@ -183,10 +191,11 @@ class Item_Rest_Helper_Test extends Gallery_Unit_Test_Case { $request = new stdClass(); $request->url = rest::url("item", $album1); $request->params = new stdClass(); - $request->params->type = "album"; - $request->params->name = "my album"; - $request->params->title = "my album"; - $request->params->slug = "not url safe"; + $request->params->entity = new stdClass(); + $request->params->entity->type = "album"; + $request->params->entity->name = "my album"; + $request->params->entity->title = "my album"; + $request->params->entity->slug = "not url safe"; try { item_rest::post($request); @@ -205,8 +214,9 @@ class Item_Rest_Helper_Test extends Gallery_Unit_Test_Case { $request = new stdClass(); $request->url = rest::url("item", $album1); $request->params = new stdClass(); - $request->params->type = "photo"; - $request->params->name = "my photo.jpg"; + $request->params->entity = new stdClass(); + $request->params->entity->type = "photo"; + $request->params->entity->name = "my photo.jpg"; $request->file = MODPATH . "gallery/tests/test.jpg"; $response = item_rest::post($request); $new_photo = rest::resolve($response["url"]); diff --git a/modules/gallery/tests/xss_data.txt b/modules/gallery/tests/xss_data.txt index a3ca31f4..afad9e13 100644 --- a/modules/gallery/tests/xss_data.txt +++ b/modules/gallery/tests/xss_data.txt @@ -70,12 +70,12 @@ modules/gallery/views/admin_graphics_imagemagick.html.php 2 DIRTY_ATTR $is_ modules/gallery/views/admin_graphics_imagemagick.html.php 2 DIRTY_ATTR $tk->installed?" g-installed-toolkit":" g-unavailable" modules/gallery/views/admin_graphics_imagemagick.html.php 18 DIRTY $tk->error modules/gallery/views/admin_languages.html.php 43 DIRTY access::csrf_form_field() -modules/gallery/views/admin_languages.html.php 60 DIRTY_ATTR (isset($installed_locales[$code]))?"g-available":"" -modules/gallery/views/admin_languages.html.php 60 DIRTY_ATTR ($default_locale==$code)?" g-selected":"" -modules/gallery/views/admin_languages.html.php 61 DIRTY form::checkbox("installed_locales[]",$code,isset($installed_locales[$code])) -modules/gallery/views/admin_languages.html.php 62 DIRTY $display_name -modules/gallery/views/admin_languages.html.php 64 DIRTY form::radio("default_locale",$code,($default_locale==$code),((isset($installed_locales[$code]))?'':'disabled="disabled"')) -modules/gallery/views/admin_languages.html.php 109 DIRTY $share_translations_form +modules/gallery/views/admin_languages.html.php 61 DIRTY_ATTR (isset($installed_locales[$code]))?"g-available":"" +modules/gallery/views/admin_languages.html.php 61 DIRTY_ATTR ($default_locale==$code)?" g-selected":"" +modules/gallery/views/admin_languages.html.php 62 DIRTY form::checkbox("installed_locales[]",$code,isset($installed_locales[$code])) +modules/gallery/views/admin_languages.html.php 63 DIRTY $display_name +modules/gallery/views/admin_languages.html.php 65 DIRTY form::radio("default_locale",$code,($default_locale==$code),((isset($installed_locales[$code]))?'':'disabled="disabled"')) +modules/gallery/views/admin_languages.html.php 110 DIRTY $share_translations_form modules/gallery/views/admin_maintenance.html.php 24 DIRTY_ATTR text::alternate("g-odd","g-even") modules/gallery/views/admin_maintenance.html.php 24 DIRTY_ATTR log::severity_class($task->severity) modules/gallery/views/admin_maintenance.html.php 25 DIRTY_ATTR log::severity_class($task->severity) @@ -121,10 +121,10 @@ modules/gallery/views/admin_themes.html.php 76 DIRTY $info- modules/gallery/views/admin_themes.html.php 78 DIRTY $info->description modules/gallery/views/admin_themes_preview.html.php 7 DIRTY_ATTR $url modules/gallery/views/error_404.html.php 14 DIRTY $login_form -modules/gallery/views/form_uploadify.html.php 30 DIRTY_JS url::file("lib/uploadify/uploadify.swf") -modules/gallery/views/form_uploadify.html.php 31 DIRTY_JS url::site("simple_uploader/add_photo/{$album->id}") -modules/gallery/views/form_uploadify.html.php 35 DIRTY_JS url::file("lib/uploadify/cancel.png") -modules/gallery/views/form_uploadify.html.php 36 DIRTY_JS $simultaneous_upload_limit +modules/gallery/views/form_uploadify.html.php 9 DIRTY_JS url::file("lib/uploadify/uploadify.swf") +modules/gallery/views/form_uploadify.html.php 10 DIRTY_JS url::site("simple_uploader/add_photo/{$album->id}") +modules/gallery/views/form_uploadify.html.php 14 DIRTY_JS url::file("lib/uploadify/cancel.png") +modules/gallery/views/form_uploadify.html.php 15 DIRTY_JS $simultaneous_upload_limit modules/gallery/views/in_place_edit.html.php 2 DIRTY form::open($action,array("method"=>"post","id"=>"g-in-place-edit-form","class"=>"g-short-form")) modules/gallery/views/in_place_edit.html.php 3 DIRTY access::csrf_form_field() modules/gallery/views/in_place_edit.html.php 6 DIRTY form::input("input",$form["input"]," class=\"textbox\"") @@ -320,19 +320,20 @@ modules/user/views/admin_users_group.html.php 24 DIRTY_JS $group modules/watermark/views/admin_watermarks.html.php 20 DIRTY_ATTR $width modules/watermark/views/admin_watermarks.html.php 20 DIRTY_ATTR $height modules/watermark/views/admin_watermarks.html.php 20 DIRTY_ATTR $url -themes/admin_wind/views/admin.html.php 16 DIRTY_JS $theme->url() -themes/admin_wind/views/admin.html.php 33 DIRTY $theme->admin_head() -themes/admin_wind/views/admin.html.php 37 DIRTY $theme->admin_page_top() -themes/admin_wind/views/admin.html.php 45 DIRTY $theme->admin_header_top() -themes/admin_wind/views/admin.html.php 46 DIRTY_JS item::root()->url() -themes/admin_wind/views/admin.html.php 49 DIRTY $theme->user_menu() -themes/admin_wind/views/admin.html.php 51 DIRTY $theme->admin_menu() -themes/admin_wind/views/admin.html.php 53 DIRTY $theme->admin_header_bottom() -themes/admin_wind/views/admin.html.php 60 DIRTY $content -themes/admin_wind/views/admin.html.php 66 DIRTY $sidebar -themes/admin_wind/views/admin.html.php 71 DIRTY $theme->admin_footer() -themes/admin_wind/views/admin.html.php 73 DIRTY $theme->admin_credits() -themes/admin_wind/views/admin.html.php 77 DIRTY $theme->admin_page_bottom() +themes/admin_wind/views/admin.html.php 9 DIRTY $page_title +themes/admin_wind/views/admin.html.php 22 DIRTY_JS $theme->url() +themes/admin_wind/views/admin.html.php 39 DIRTY $theme->admin_head() +themes/admin_wind/views/admin.html.php 43 DIRTY $theme->admin_page_top() +themes/admin_wind/views/admin.html.php 51 DIRTY $theme->admin_header_top() +themes/admin_wind/views/admin.html.php 52 DIRTY_JS item::root()->url() +themes/admin_wind/views/admin.html.php 55 DIRTY $theme->user_menu() +themes/admin_wind/views/admin.html.php 57 DIRTY $theme->admin_menu() +themes/admin_wind/views/admin.html.php 59 DIRTY $theme->admin_header_bottom() +themes/admin_wind/views/admin.html.php 66 DIRTY $content +themes/admin_wind/views/admin.html.php 72 DIRTY $sidebar +themes/admin_wind/views/admin.html.php 77 DIRTY $theme->admin_footer() +themes/admin_wind/views/admin.html.php 79 DIRTY $theme->admin_credits() +themes/admin_wind/views/admin.html.php 83 DIRTY $theme->admin_page_bottom() themes/admin_wind/views/block.html.php 3 DIRTY_ATTR $anchor themes/admin_wind/views/block.html.php 5 DIRTY $id themes/admin_wind/views/block.html.php 5 DIRTY_ATTR $css_id diff --git a/modules/gallery/views/movieplayer.html.php b/modules/gallery/views/movieplayer.html.php index f7af8d93..2e79b620 100644 --- a/modules/gallery/views/movieplayer.html.php +++ b/modules/gallery/views/movieplayer.html.php @@ -5,12 +5,13 @@ "<?= $attrs["id"] ?>", { src: "<?= url::abs_file("lib/flowplayer.swf") ?>", - wmode: "transparent" + wmode: "transparent", + provider: "pseudostreaming" }, { plugins: { - h264streaming: { - url: "<?= url::abs_file("lib/flowplayer.h264streaming.swf") ?>" + pseudostreaming: { + url: "<?= url::abs_file("lib/flowplayer.pseudostreaming.swf") ?>" }, controls: { autoHide: 'always', diff --git a/modules/recaptcha/controllers/admin_recaptcha.php b/modules/recaptcha/controllers/admin_recaptcha.php index 3f2959a5..264d3177 100644 --- a/modules/recaptcha/controllers/admin_recaptcha.php +++ b/modules/recaptcha/controllers/admin_recaptcha.php @@ -51,6 +51,7 @@ class Admin_Recaptcha_Controller extends Admin_Controller { recaptcha::check_config(); $view = new Admin_View("admin.html"); + $view->page_title = t("reCAPTCHA"); $view->content = new View("admin_recaptcha.html"); $view->content->public_key = module::get_var("recaptcha", "public_key"); $view->content->private_key = module::get_var("recaptcha", "private_key"); diff --git a/modules/rest/controllers/rest.php b/modules/rest/controllers/rest.php index 9f9b9aff..dab54976 100644 --- a/modules/rest/controllers/rest.php +++ b/modules/rest/controllers/rest.php @@ -34,7 +34,7 @@ class Rest_Controller extends Controller { auth::login($user); - $key = rest::get_access_token($user->id); + $key = rest::get_access_key($user->id); rest::reply($key->access_key); } @@ -54,11 +54,18 @@ class Rest_Controller extends Controller { break; } + if (isset($request->params->entity)) { + $request->params->entity = json_decode($request->params->entity); + } + if (isset($request->params->members)) { + $request->params->members = json_decode($request->params->members); + } + $request->method = strtolower($input->server("HTTP_X_GALLERY_REQUEST_METHOD", $method)); - $request->access_token = $input->server("HTTP_X_GALLERY_REQUEST_KEY"); + $request->access_key = $input->server("HTTP_X_GALLERY_REQUEST_KEY"); $request->url = url::abs_current(true); - rest::set_active_user($request->access_token); + rest::set_active_user($request->access_key); $handler_class = "{$function}_rest"; $handler_method = $request->method; diff --git a/modules/rest/helpers/rest.php b/modules/rest/helpers/rest.php index 7440350f..49999520 100644 --- a/modules/rest/helpers/rest.php +++ b/modules/rest/helpers/rest.php @@ -37,13 +37,13 @@ class rest_Core { } } - static function set_active_user($access_token) { - if (empty($access_token)) { + static function set_active_user($access_key) { + if (empty($access_key)) { throw new Rest_Exception("Forbidden", 403); } - $key = ORM::factory("user_access_token") - ->where("access_key", "=", $access_token) + $key = ORM::factory("user_access_key") + ->where("access_key", "=", $access_key) ->find(); if (!$key->loaded()) { @@ -58,8 +58,8 @@ class rest_Core { identity::set_active_user($user); } - static function get_access_token($user_id) { - $key = ORM::factory("user_access_token") + static function get_access_key($user_id) { + $key = ORM::factory("user_access_key") ->where("user_id", "=", $user_id) ->find(); diff --git a/modules/rest/helpers/rest_event.php b/modules/rest/helpers/rest_event.php index 91affe7a..e4e53ef6 100644 --- a/modules/rest/helpers/rest_event.php +++ b/modules/rest/helpers/rest_event.php @@ -24,7 +24,7 @@ class rest_event { */ static function user_before_delete($user) { db::build() - ->delete("user_access_tokens") + ->delete("user_access_keys") ->where("id", "=", $user->id) ->execute(); } @@ -34,7 +34,7 @@ class rest_event { * on every add. */ static function user_add_form_admin_completed($user, $form) { - $key = ORM::factory("user_access_token"); + $key = ORM::factory("user_access_key"); $key->user_id = $user->id; $key->access_key = md5($user->name . rand()); $key->save(); @@ -58,7 +58,7 @@ class rest_event { * Get the form fields for user edit */ static function _get_access_key_form($user, $form) { - $key = ORM::factory("user_access_token") + $key = ORM::factory("user_access_key") ->where("user_id", "=", $user->id) ->find(); @@ -68,7 +68,7 @@ class rest_event { $key->save(); } - $form->edit_user->input("user_access_token") + $form->edit_user->input("user_access_key") ->value($key->access_key) ->readonly("readonly") ->class("g-form-static") @@ -87,9 +87,9 @@ class rest_event { } $view = new View("user_profile_rest.html"); - $key = ORM::factory("user_access_token") - ->where("user_id", "=", $data->user->id) - ->find(); + $key = ORM::factory("user_access_key") + ->where("user_id", "=", $data->user->id) + ->find(); if (!$key->loaded()) { $key->user_id = $data->user->id; @@ -97,6 +97,6 @@ class rest_event { $key->save(); } $view->rest_key = $key->access_key; - $data->content[] = (object)array("title" => t("Rest api"), "view" => $view); + $data->content[] = (object)array("title" => t("REST api"), "view" => $view); } } diff --git a/modules/rest/helpers/rest_installer.php b/modules/rest/helpers/rest_installer.php index f69f62d1..aeb9573e 100644 --- a/modules/rest/helpers/rest_installer.php +++ b/modules/rest/helpers/rest_installer.php @@ -20,7 +20,7 @@ class rest_installer { static function install() { Database::instance() - ->query("CREATE TABLE {user_access_tokens} ( + ->query("CREATE TABLE {user_access_keys} ( `id` int(9) NOT NULL auto_increment, `user_id` int(9) NOT NULL, `access_key` char(32) NOT NULL, @@ -28,10 +28,18 @@ class rest_installer { UNIQUE KEY(`access_key`), UNIQUE KEY(`user_id`)) DEFAULT CHARSET=utf8;"); - module::set_version("rest", 1); + module::set_version("rest", 2); + } + + static function upgrade($version) { + $db = Database::instance(); + if ($version == 1) { + $db->query("RENAME TABLE {user_access_tokens} TO {user_access_keys}"); + module::set_version("rest", $version = 2); + } } static function uninstall() { - Database::instance()->query("DROP TABLE IF EXISTS {user_access_tokens}"); + Database::instance()->query("DROP TABLE IF EXISTS {user_access_keys}"); } } diff --git a/modules/rest/models/user_access_token.php b/modules/rest/models/user_access_key.php index 44330768..1da0f5eb 100644 --- a/modules/rest/models/user_access_token.php +++ b/modules/rest/models/user_access_key.php @@ -17,5 +17,5 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class User_Access_Token_Model extends ORM { +class User_Access_Key_Model extends ORM { } diff --git a/modules/rest/module.info b/modules/rest/module.info index 45bd79e4..3ab7e165 100644 --- a/modules/rest/module.info +++ b/modules/rest/module.info @@ -1,4 +1,4 @@ name = "REST Access Module" description = "The RESTful implementation/interface to Gallery3" -version = 1 +version = 2 diff --git a/modules/rest/tests/Rest_Controller_Test.php b/modules/rest/tests/Rest_Controller_Test.php index 21be8300..fe83283d 100644 --- a/modules/rest/tests/Rest_Controller_Test.php +++ b/modules/rest/tests/Rest_Controller_Test.php @@ -21,12 +21,13 @@ class Rest_Controller_Test extends Gallery_Unit_Test_Case { public function setup() { $this->_save = array($_GET, $_POST, $_SERVER); - $key = rest::get_access_token(1); // admin user + $key = rest::get_access_key(1); // admin user $_SERVER["HTTP_X_GALLERY_REQUEST_KEY"] = $key->access_key; } public function teardown() { list($_GET, $_POST, $_SERVER) = $this->_save; + identity::set_active_user(identity::admin_user()); } public function login_test() { @@ -34,14 +35,14 @@ class Rest_Controller_Test extends Gallery_Unit_Test_Case { // There's no access key at first $this->assert_false( - ORM::factory("user_access_token")->where("user_id", "=", $user->id)->find()->loaded()); + ORM::factory("user_access_key")->where("user_id", "=", $user->id)->find()->loaded()); $_POST["user"] = $user->name; $_POST["password"] = "password"; $response = test::call_and_capture(array(new Rest_Controller(), "index")); $expected = - ORM::factory("user_access_token")->where("user_id", "=", $user->id)->find()->access_key; + ORM::factory("user_access_key")->where("user_id", "=", $user->id)->find()->access_key; // Now there is an access key, and it was returned $this->assert_equal(json_encode($expected), $response); @@ -82,11 +83,11 @@ class Rest_Controller_Test extends Gallery_Unit_Test_Case { $_SERVER["REQUEST_METHOD"] = "GET"; $_GET["key"] = "value"; - $key = rest::get_access_token(1); // admin user + $key = rest::get_access_key(1); // admin user $this->assert_array_equal_to_json( array("params" => array("key" => "value"), "method" => "get", - "access_token" => $key->access_key, + "access_key" => $key->access_key, "url" => "http://./index.php/gallery_unit_test"), test::call_and_capture(array(new Rest_Controller(), "mock"))); } @@ -95,11 +96,11 @@ class Rest_Controller_Test extends Gallery_Unit_Test_Case { $_SERVER["REQUEST_METHOD"] = "POST"; $_POST["key"] = "value"; - $key = rest::get_access_token(1); // admin user + $key = rest::get_access_key(1); // admin user $this->assert_array_equal_to_json( array("params" => array("key" => "value"), "method" => "post", - "access_token" => $key->access_key, + "access_key" => $key->access_key, "url" => "http://./index.php/gallery_unit_test"), test::call_and_capture(array(new Rest_Controller(), "mock"))); } @@ -109,11 +110,11 @@ class Rest_Controller_Test extends Gallery_Unit_Test_Case { $_SERVER["HTTP_X_GALLERY_REQUEST_METHOD"] = "put"; $_POST["key"] = "value"; - $key = rest::get_access_token(1); // admin user + $key = rest::get_access_key(1); // admin user $this->assert_array_equal_to_json( array("params" => array("key" => "value"), "method" => "put", - "access_token" => $key->access_key, + "access_key" => $key->access_key, "url" => "http://./index.php/gallery_unit_test"), test::call_and_capture(array(new Rest_Controller(), "mock"))); } @@ -123,11 +124,11 @@ class Rest_Controller_Test extends Gallery_Unit_Test_Case { $_SERVER["HTTP_X_GALLERY_REQUEST_METHOD"] = "delete"; $_POST["key"] = "value"; - $key = rest::get_access_token(1); // admin user + $key = rest::get_access_key(1); // admin user $this->assert_array_equal_to_json( array("params" => array("key" => "value"), "method" => "delete", - "access_token" => $key->access_key, + "access_key" => $key->access_key, "url" => "http://./index.php/gallery_unit_test"), test::call_and_capture(array(new Rest_Controller(), "mock"))); } diff --git a/modules/server_add/controllers/admin_server_add.php b/modules/server_add/controllers/admin_server_add.php index 7ffba361..2e743c81 100644 --- a/modules/server_add/controllers/admin_server_add.php +++ b/modules/server_add/controllers/admin_server_add.php @@ -20,6 +20,7 @@ class Admin_Server_Add_Controller extends Admin_Controller { public function index() { $view = new Admin_View("admin.html"); + $view->page_title = t("Add from server"); $view->content = new View("admin_server_add.html"); $view->content->form = $this->_get_admin_form(); $paths = unserialize(module::get_var("server_add", "authorized_paths", "a:0:{}")); diff --git a/modules/server_add/controllers/server_add.php b/modules/server_add/controllers/server_add.php index 3e460f20..715274ab 100644 --- a/modules/server_add/controllers/server_add.php +++ b/modules/server_add/controllers/server_add.php @@ -156,6 +156,7 @@ class Server_Add_Controller extends Admin_Controller { $entry_id = null; } + $file = preg_quote($file); foreach (glob("$file/*") as $child) { if (is_dir($child)) { $queue[] = array($child, $entry_id); diff --git a/modules/tag/controllers/admin_tags.php b/modules/tag/controllers/admin_tags.php index 03a14814..9e875d14 100644 --- a/modules/tag/controllers/admin_tags.php +++ b/modules/tag/controllers/admin_tags.php @@ -22,6 +22,7 @@ class Admin_Tags_Controller extends Admin_Controller { $filter = Input::instance()->get("filter"); $view = new Admin_View("admin.html"); + $view->page_title = t("Manage tags"); $view->content = new View("admin_tags.html"); $view->content->filter = $filter; diff --git a/modules/tag/helpers/item_tags_rest.php b/modules/tag/helpers/item_tags_rest.php index 8a1b1e8b..02c79e5d 100644 --- a/modules/tag/helpers/item_tags_rest.php +++ b/modules/tag/helpers/item_tags_rest.php @@ -31,8 +31,8 @@ class item_tags_rest_Core { } static function post($request) { - $tag = rest::resolve($request->params->tag); - $item = rest::resolve($request->params->item); + $tag = rest::resolve($request->params->entity->tag); + $item = rest::resolve($request->params->entity->item); access::required("view", $item); tag::add($item, $tag->name); @@ -45,6 +45,7 @@ class item_tags_rest_Core { static function delete($request) { list ($tag, $item) = rest::resolve($request->url); + access::required("edit", $item); $tag->remove($item); $tag->save(); } diff --git a/modules/tag/helpers/tag.php b/modules/tag/helpers/tag.php index 8df4210d..14d27c94 100644 --- a/modules/tag/helpers/tag.php +++ b/modules/tag/helpers/tag.php @@ -98,7 +98,7 @@ class tag_Core { ($item->is_photo() ? t("Add tag to photo") : t("Add tag to movie")); $group = $form->group("add_tag")->label("Add Tag"); - $group->input("name")->label($label)->rules("required"); + $group->input("name")->label($label)->rules("required")->id("name"); $group->hidden("item_id")->value($item->id); $group->submit("")->value(t("Add Tag")); return $form; diff --git a/modules/tag/helpers/tag_item_rest.php b/modules/tag/helpers/tag_item_rest.php index bce00a9f..17cb726e 100644 --- a/modules/tag/helpers/tag_item_rest.php +++ b/modules/tag/helpers/tag_item_rest.php @@ -22,7 +22,7 @@ class tag_item_rest_Core { list ($tag, $item) = rest::resolve($request->url); return array( "url" => $request->url, - "members" => array( + "entity" => array( "tag" => rest::url("tag", $tag), "item" => rest::url("item", $item))); } diff --git a/modules/tag/helpers/tag_items_rest.php b/modules/tag/helpers/tag_items_rest.php index 003c7c95..848c2cd3 100644 --- a/modules/tag/helpers/tag_items_rest.php +++ b/modules/tag/helpers/tag_items_rest.php @@ -33,8 +33,8 @@ class tag_items_rest_Core { } static function post($request) { - $tag = rest::resolve($request->params->tag); - $item = rest::resolve($request->params->item); + $tag = rest::resolve($request->params->entity->tag); + $item = rest::resolve($request->params->entity->item); access::required("view", $item); if (!$tag->loaded()) { diff --git a/modules/tag/helpers/tag_rest.php b/modules/tag/helpers/tag_rest.php index f30706bd..e0b7bd87 100644 --- a/modules/tag/helpers/tag_rest.php +++ b/modules/tag/helpers/tag_rest.php @@ -36,28 +36,25 @@ class tag_rest_Core { "members" => $tag_items))); } - static function post($request) { - if (empty($request->params->url)) { - throw new Rest_Exception("Bad request", 400); - } - - $tag = rest::resolve($request->url); - $item = rest::resolve($request->params->url); - access::required("edit", $item); - - tag::add($item, $tag->name); - return array("url" => rest::url("tag_item", $tag, $item)); - } - static function put($request) { + // Who can we allow to edit a tag name? If we allow anybody to do it then any logged in + // user can rename all your tags to something offensive. Right now limit renaming to admins. + if (!identity::active_user()->admin) { + access::forbidden(); + } $tag = rest::resolve($request->url); - if (isset($request->params->name)) { - $tag->name = $request->params->name; + if (isset($request->params->entity->name)) { + $tag->name = $request->params->entity->name; $tag->save(); } } static function delete($request) { + // Restrict deleting tags to admins. Otherwise, a logged in user can do great harm to an + // install. + if (!identity::active_user()->admin) { + access::forbidden(); + } $tag = rest::resolve($request->url); $tag->delete(); } diff --git a/modules/tag/helpers/tags_rest.php b/modules/tag/helpers/tags_rest.php index 82826d8e..434e774a 100644 --- a/modules/tag/helpers/tags_rest.php +++ b/modules/tag/helpers/tags_rest.php @@ -40,13 +40,13 @@ class tags_rest_Core { } } - if (empty($request->params->name)) { + if (empty($request->params->entity->name)) { throw new Rest_Exception("Bad Request", 400); } - $tag = ORM::factory("tag")->where("name", "=", $request->params->name)->find(); + $tag = ORM::factory("tag")->where("name", "=", $request->params->entity->name)->find(); if (!$tag->loaded()) { - $tag->name = $request->params->name; + $tag->name = $request->params->entity->name; $tag->count = 0; $tag->save(); } diff --git a/modules/tag/tests/Tag_Item_Rest_Helper_Test.php b/modules/tag/tests/Tag_Item_Rest_Helper_Test.php index e5acab93..533f832d 100644 --- a/modules/tag/tests/Tag_Item_Rest_Helper_Test.php +++ b/modules/tag/tests/Tag_Item_Rest_Helper_Test.php @@ -32,7 +32,7 @@ class Tag_Item_Rest_Helper_Test extends Gallery_Unit_Test_Case { $request->url = rest::url("tag_item", $tag, item::root()); $this->assert_equal_array( array("url" => rest::url("tag_item", $tag, item::root()), - "members" => array( + "entity" => array( "tag" => rest::url("tag", $tag), "item" => rest::url("item", item::root()))), tag_item_rest::get($request)); diff --git a/modules/tag/tests/Tag_Rest_Helper_Test.php b/modules/tag/tests/Tag_Rest_Helper_Test.php index f4d5a14a..a8aa89d4 100644 --- a/modules/tag/tests/Tag_Rest_Helper_Test.php +++ b/modules/tag/tests/Tag_Rest_Helper_Test.php @@ -67,41 +67,13 @@ class Tag_Rest_Helper_Test extends Gallery_Unit_Test_Case { tag_rest::get($request)); } - public function post_test() { - $tag = test::random_tag(); - - // Create an editable item to be tagged - $album = test::random_album(); - access::allow(identity::everybody(), "edit", $album); - - // Add the album to the tag - $request = new stdClass(); - $request->url = rest::url("tag", $tag); - $request->params = new stdClass(); - $request->params->url = rest::url("item", $album); - $this->assert_equal_array( - array("url" => rest::url("tag_item", $tag, $album)), - tag_rest::post($request)); - } - - public function post_with_no_item_url_test() { - $request = new stdClass(); - try { - tag_rest::post($request); - } catch (Rest_Exception $e) { - $this->assert_equal(400, $e->getCode()); - return; - } - - $this->assert_true(false, "Shouldn't get here"); - } - public function put_test() { $tag = test::random_tag(); $request = new stdClass(); $request->url = rest::url("tag", $tag); $request->params = new stdClass(); - $request->params->name = "new name"; + $request->params->entity = new stdClass(); + $request->params->entity->name = "new name"; tag_rest::put($request); $this->assert_equal("new name", $tag->reload()->name); diff --git a/modules/tag/tests/Tags_Rest_Helper_Test.php b/modules/tag/tests/Tags_Rest_Helper_Test.php index a0ebc8c3..99332c7c 100644 --- a/modules/tag/tests/Tags_Rest_Helper_Test.php +++ b/modules/tag/tests/Tags_Rest_Helper_Test.php @@ -45,11 +45,12 @@ class Tags_Rest_Helper_Test extends Gallery_Unit_Test_Case { } public function post_test() { - access::allow(identity::everybody(), "edit", item::root()); + identity::set_active_user(identity::guest()); $request = new stdClass(); $request->params = new stdClass(); - $request->params->name = "test tag"; + $request->params->entity = new stdClass(); + $request->params->entity->name = "test tag"; $this->assert_equal( array("url" => url::site("rest/tag/1")), tags_rest::post($request)); @@ -63,7 +64,8 @@ class Tags_Rest_Helper_Test extends Gallery_Unit_Test_Case { try { $request = new stdClass(); $request->params = new stdClass(); - $request->params->name = "test tag"; + $request->params->entity = new stdClass(); + $request->params->entity->name = "test tag"; tags_rest::post($request); } catch (Exception $e) { $this->assert_equal(403, $e->getCode()); diff --git a/modules/tag/views/admin_tags.html.php b/modules/tag/views/admin_tags.html.php index b637a7f1..e1db387b 100644 --- a/modules/tag/views/admin_tags.html.php +++ b/modules/tag/views/admin_tags.html.php @@ -16,7 +16,7 @@ <? $column_tag_count = 0 ?> <div class="g-block"> - <h1> <?= t("Tag Admin") ?> </h1> + <h1> <?= t("Manage tags") ?> </h1> <div class="g-block-content"> <table id="g-tag-admin"> diff --git a/modules/user/controllers/admin_users.php b/modules/user/controllers/admin_users.php index 3e36fd67..e14be393 100644 --- a/modules/user/controllers/admin_users.php +++ b/modules/user/controllers/admin_users.php @@ -20,6 +20,7 @@ class Admin_Users_Controller extends Admin_Controller { public function index() { $view = new Admin_View("admin.html"); + $view->page_title = t("Users and groups"); $view->content = new View("admin_users.html"); $view->content->users = ORM::factory("user")->order_by("name", "ASC")->find_all(); $view->content->groups = ORM::factory("group")->order_by("name", "ASC")->find_all(); diff --git a/modules/user/controllers/users.php b/modules/user/controllers/users.php index e1f1fa2b..7f3f6b1f 100644 --- a/modules/user/controllers/users.php +++ b/modules/user/controllers/users.php @@ -167,7 +167,7 @@ class Users_Controller extends Controller { $group->password("old_password")->label(t("Old password"))->id("g-password") ->callback("auth::validate_too_many_failed_auth_attempts") ->callback("user::valid_password") - ->error_messages("invalid", t("Incorrect password")) + ->error_messages("invalid_password", t("Incorrect password")) ->error_messages( "too_many_failed_auth_attempts", t("Too many incorrect passwords. Try again later")); diff --git a/modules/user/helpers/user.php b/modules/user/helpers/user.php index 650dcf6a..55153263 100644 --- a/modules/user/helpers/user.php +++ b/modules/user/helpers/user.php @@ -72,7 +72,13 @@ class user_Core { static function valid_password($password_input) { if (!user::is_correct_password(identity::active_user(), $password_input->value)) { - $password_input->add_error("invalid", 1); + $password_input->add_error("invalid_password", 1); + } + } + + static function valid_username($text_input) { + if (!self::lookup_by_name($text_input->value)) { + $text_input->add_error("invalid_username", 1); } } diff --git a/modules/watermark/controllers/admin_watermarks.php b/modules/watermark/controllers/admin_watermarks.php index aa5be8db..d26919d5 100644 --- a/modules/watermark/controllers/admin_watermarks.php +++ b/modules/watermark/controllers/admin_watermarks.php @@ -22,6 +22,7 @@ class Admin_Watermarks_Controller extends Admin_Controller { $name = module::get_var("watermark", "name"); $view = new Admin_View("admin.html"); + $view->page_title = t("Watermarks"); $view->content = new View("admin_watermarks.html"); if ($name) { $view->content->name = module::get_var("watermark", "name"); diff --git a/themes/wind/css/screen.css b/themes/wind/css/screen.css index e96b259d..f8e26073 100644 --- a/themes/wind/css/screen.css +++ b/themes/wind/css/screen.css @@ -213,10 +213,16 @@ td { padding-left: 0; } +/* Sidebar ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + #g-sidebar .g-block-content { padding-left: 1em; } +#g-sidebar #g-image-block { + overflow: hidden; +} + /* Album content ~~~~~~~~~~~~~~~~~~~~~~~~~ */ #g-content #g-album-grid { diff --git a/themes/wind/views/page.html.php b/themes/wind/views/page.html.php index 61e34145..ebfbf700 100644 --- a/themes/wind/views/page.html.php +++ b/themes/wind/views/page.html.php @@ -35,10 +35,10 @@ <![endif]--> <? if ($theme->page_type == "collection"): ?> <? if ($thumb_proportion != 1): ?> - <? $new_width = $thumb_proportion * 213 ?> - <? $new_height = $thumb_proportion * 240 ?> + <? $new_width = round($thumb_proportion * 213) ?> + <? $new_height = round($thumb_proportion * 240) ?> <style type="text/css"> - #g-content #g-album-grid .g-item { + .g-view #g-content #g-album-grid .g-item { width: <?= $new_width ?>px; height: <?= $new_height ?>px; /* <?= $thumb_proportion ?> */ |