This commit is contained in:
Stian Lund 2024-03-03 13:51:38 +01:00
commit 7d68ea5227
1139 changed files with 59195 additions and 0 deletions

32
README.md Normal file
View File

@ -0,0 +1,32 @@
modules/:
albumtree
arrow_nav
batchtag
captionator
custom_menus
database_info
delete_cache
downloadfullsize
dupcheck
exif_gps
gallerystats
greydragon
image_fit
latestupdates
moduleorder
movie_tools
permissions_dialog_usability
reset_counts
rwinfo
tag_cloud_page
themedispatcher
treeview
user_info
themes/:
clean_canvas
greydragon
greydragon_wide_wind
imobile
smk
widesmk

View File

@ -0,0 +1,134 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 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 Admin_Navcarousel_Controller extends Admin_Controller {
public function index() {
print $this->_get_view();
}
public function handler() {
access::verify_csrf();
$form = $this->_get_form();
if ($form->validate()) {
$scrollsize = intval($form->navcarousel->scrollsize->value);
$showelements = intval($form->navcarousel->showelements->value);
$carouselwidth = intval($form->navcarousel->carouselwidth->value);
$thumbsize = intval($form->thumbsettings->thumbsize->value);
if ($showelements < 1) {
$showelements = 1;
message::error(t("You must show at least one item."));
}
if ($scrollsize < 1) {
$scrollsize = 1;
message::error(t("You must scroll by at least one item."));
}
if ($thumbsize > 150 || $thumbsize < 25) {
$thumbsize = 50;
message::error(t("The size of the thumbnails must be between 25 and 150 pixel."));
}
if ($carouselwidth < ($thumbsize + 75) && $carouselwidth > 0) {
$carouselwidth = $thumbsize + 75;
message::error(t("The carousel must be at least %pixel wide.", array("pixel" => $carouselwidth)));
}
if ($carouselwidth > 0) {
if ($carouselwidth < ((($thumbsize + 11) * $showelements) + 64)) {
$showelements = ($carouselwidth - 64) / ($thumbsize + 11);
$showelements = intval(floor($showelements));
message::error(t("With the selected carousel width and thumbnail size you can show a maximum of %itemno items.", array("itemno" => $showelements)));
}
} else {
message::warning(t("The maximum number of displayable items cannot be calculated when the carousel width is set to 0."));
}
if ($scrollsize > $showelements) {
$scrollsize = $showelements;
message::error(t("The number of items to scroll must not exceed the number of items to show."));
}
module::set_var(
"navcarousel", "scrollsize", $scrollsize);
module::set_var(
"navcarousel", "showelements", $showelements);
module::set_var(
"navcarousel", "carouselwidth", $carouselwidth);
module::set_var(
"navcarousel", "thumbsize", $thumbsize);
module::set_var(
"navcarousel", "abovephoto", $form->navcarousel->abovephoto->value, true);
module::set_var(
"navcarousel", "noajax", $form->navcarousel->noajax->value, true);
module::set_var(
"navcarousel", "showondomready", $form->navcarousel->showondomready->value, true);
module::set_var(
"navcarousel", "maintainaspect", $form->thumbsettings->maintainaspect->value, true);
module::set_var(
"navcarousel", "nomouseover", $form->thumbsettings->nomouseover->value, true);
module::set_var(
"navcarousel", "noresize", $form->thumbsettings->noresize->value, true);
message::success(t("Your settings have been saved."));
url::redirect("admin/navcarousel");
}
print $this->_get_view($form);
}
private function _get_view($form=null) {
$v = new Admin_View("admin.html");
$v->content = new View("admin_navcarousel.html");
$v->content->form = empty($form) ? $this->_get_form() : $form;
return $v;
}
private function _get_form() {
$form = new Forge("admin/navcarousel/handler", "", "post", array("id" => "g-admin-form"));
$group = $form->group("navcarousel")->label(t("Navigation carousel settings"));
$group->input("scrollsize")->label(t('Enter how many items you want to scroll when clicking next or previous'))
->value(module::get_var("navcarousel", "scrollsize", "7"))
->rules("valid_numeric|length[1,2]");
$group->input("showelements")->label(t('Enter how many items you want to be visible'))
->value(module::get_var("navcarousel", "showelements", "7"))
->rules("valid_numeric|length[1,2]");
$group->input("carouselwidth")->label(t('Carousel width (in pixel). If set to 0 the carousel will use the full available width.'))
->value(module::get_var("navcarousel", "carouselwidth", "600"))
->rules("valid_numeric|length[1,3]");
$group->checkbox("abovephoto")->label(t("Show carousel above photo"))
->checked(module::get_var("navcarousel", "abovephoto", false));
$group->checkbox("noajax")->label(t("Disable dynamic loading of thumbnails (might be slow for big albums)"))
->checked(module::get_var("navcarousel", "noajax", false));
$group->checkbox("showondomready")->label(t("Show carousel before all items are loaded (faster loading on large albums but might cause too early display on Chrome and Opera)"))
->checked(module::get_var("navcarousel", "showondomready", false));
$group = $form->group("thumbsettings")->label(t("Change how thumnails are displayed"));
$group->input("thumbsize")->label(t('Thumbnail size (in pixel)'))
->value(module::get_var("navcarousel", "thumbsize", "50"))
->rules("valid_numeric|length[1,3]");
$group->checkbox("nomouseover")->label(t("Do not show item title and number on mouse over"))
->checked(module::get_var("navcarousel", "nomouseover", false));
$group->checkbox("noresize")->label(t("Crop thumbails instead of resizing them."))
->onClick("changeaspectstate()")
->id("noresize")
->checked(module::get_var("navcarousel", "noresize", false));
$group->checkbox("maintainaspect")->label(t("Maintain aspect ratio of the items for the thumbnails."))
->id("maintainaspect")
->checked(module::get_var("navcarousel", "maintainaspect", false));
$form->submit("submit")->value(t("Save"));
return $form;
}
}

View File

@ -0,0 +1,62 @@
<?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 Navcarousel_Controller extends Controller {
public function item($itemid) {
// This function creates the xml file for jCarousel
$curritem = ORM::factory("item", $itemid);
$parent = $curritem->parent();
$item_count = -1;
// Array indexes are 0-based, jCarousel positions are 1-based.
$first = max(0, intval($_GET['first']) - 1);
$last = max($first + 1, intval($_GET['last']) - 1);
$length = $last - $first + 1;
// Build the array with the thumbnail URLs
foreach ($parent->viewable()->children() as $photo) {
if (!$photo->is_album()) {
$item_count++;
$itemlist[$item_count] = $photo->thumb_url();
}
}
$total = count($itemlist);
$selected = array_slice($itemlist, $first, $length);
// ---
header('Content-Type: text/xml');
echo '<data>';
// Return total number of images so the callback
// can set the size of the carousel.
echo ' <total>' . $total . '</total>';
foreach ($selected as $img) {
echo ' <image>' . $img . '</image>';
}
echo '</data>';
}
}

View File

@ -0,0 +1 @@
Button images copyright by Tango Icon Library Team (http://tango.freedesktop.org/Tango_Icon_Library)

View File

@ -0,0 +1,122 @@
.jcarousel-skin-tango .jcarousel-container {
-moz-border-radius: 10px;
background: transparent;
border: 0;
}
.jcarousel-skin-tango .jcarousel-container-horizontal {
padding: 0 60px;
margin: 0 auto;
}
.jcarousel-skin-tango .jcarousel-item {
background-color: transparent !important;
}
.jcarousel-skin-tango .jcarousel-item-horizontal {
margin-right: 2px;
margin-right: 2px;
padding-top: 2px;
text-align: center;
}
.jcarousel-skin-tango .jcarousel-item-placeholder {
background: #fff;
color: #000;
}
/**
* Horizontal Buttons
*/
.jcarousel-skin-tango .jcarousel-next-horizontal {
position: absolute;
right: 18px;
width: 32px;
height: 32px;
cursor: pointer;
background: transparent url('../images/next-horizontal.png') no-repeat 0 0;
visibility: hidden;
}
.jcarousel-skin-tango .jcarousel-next-horizontal:hover {
background-position: -32px 0;
}
.jcarousel-skin-tango .jcarousel-next-horizontal:active {
background-position: -64px 0;
}
.jcarousel-skin-tango .jcarousel-next-disabled-horizontal,
.jcarousel-skin-tango .jcarousel-next-disabled-horizontal:hover,
.jcarousel-skin-tango .jcarousel-next-disabled-horizontal:active {
cursor: default;
background-position: -96px 0;
}
.jcarousel-skin-tango .jcarousel-prev-horizontal {
position: absolute;
left: 18px;
width: 32px;
height: 32px;
cursor: pointer;
background: transparent url('../images/prev-horizontal.png') no-repeat 0 0;
visibility: hidden;
}
.jcarousel-skin-tango .jcarousel-prev-horizontal:hover {
background-position: -32px 0;
}
.jcarousel-skin-tango .jcarousel-prev-horizontal:active {
background-position: -64px 0;
}
.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal,
.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal:hover,
.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal:active {
cursor: default;
background-position: -96px 0;
}
.carousel-thumbnail {
padding: 5px;
margin: 0 !important;
}
.carousel-thumbnail:hover {
box-shadow: 1px 0px 8px #d7e1fa;
-moz-box-shadow: 1px 0px 8px #d7e1fa;
-webkit-box-shadow: 1px 0px 8px #d7e1fa;
}
.carousel-current {
box-shadow: 1px 0px 8px #d7e1fa;
-moz-box-shadow: 1px 0px 8px #d7e1fa;
-webkit-box-shadow: 1px 0px 8px #d7e1fa;
padding: 5px;
margin: 0 !important;
}
#navcarousel-wrapper {
width: 100%;
background: url('../images/ajax-loader.gif') no-repeat center center;
}
#navcarousel {
visibility: hidden;
}
/**
* RTL Support
*/
.jcarousel-skin-tango .jcarousel-direction-rtl {direction:rtl;}
.jcarousel-skin-tango .jcarousel-direction-rtl .jcarousel-item-horizontal{ margin-right:0; margin-left:10px;}
/*horizontal buttons*/
.jcarousel-skin-tango .jcarousel-direction-rtl .jcarousel-next-horizontal{
background-image:url('../images/prev-horizontal.png'); right:auto; left:5px;
}
.jcarousel-skin-tango .jcarousel-direction-rtl .jcarousel-prev-horizontal{
background-image:url('../images/next-horizontal.png'); left:auto; right:5px;
}

View File

@ -0,0 +1,28 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 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 navcarousel_event_Core {
static function admin_menu($menu, $theme) {
$menu->get("settings_menu")
->append(Menu::factory("link")
->id("navcarousel_menu")
->label(t("Navigation carousel"))
->url(url::site("admin/navcarousel")));
}
}

View File

@ -0,0 +1,43 @@
<?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 navcarousel_theme_Core {
static function head($theme) {
if ($theme->page_type == "item") {
return $theme->script("jquery.jcarousel.min.js")
. $theme->css("skin.css");
}
}
static function photo_bottom($theme) {
if (!module::get_var("navcarousel", "abovephoto", false)) {
if ($theme->page_type == "item") {
return new View("navcarousel.html");
}
}
}
static function photo_top($theme) {
if (module::get_var("navcarousel", "abovephoto", false)) {
if ($theme->page_type == "item") {
return new View("navcarousel.html");
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,917 @@
/*!
* jCarousel - Riding carousels with jQuery
* http://sorgalla.com/jcarousel/
*
* Copyright (c) 2006 Jan Sorgalla (http://sorgalla.com)
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
*
* Built on top of the jQuery library
* http://jquery.com
*
* Inspired by the "Carousel Component" by Bill Scott
* http://billwscott.com/carousel/
*/
(function($) {
/**
* Creates a carousel for all matched elements.
*
* @example $("#mycarousel").jcarousel();
* @before <ul id="mycarousel" class="jcarousel-skin-name"><li>First item</li><li>Second item</li></ul>
* @result
*
* <div class="jcarousel-skin-name">
* <div class="jcarousel-container">
* <div class="jcarousel-clip">
* <ul class="jcarousel-list">
* <li class="jcarousel-item-1">First item</li>
* <li class="jcarousel-item-2">Second item</li>
* </ul>
* </div>
* <div disabled="disabled" class="jcarousel-prev jcarousel-prev-disabled"></div>
* <div class="jcarousel-next"></div>
* </div>
* </div>
*
* @method jcarousel
* @return jQuery
* @param o {Hash|String} A set of key/value pairs to set as configuration properties or a method name to call on a formerly created instance.
*/
$.fn.jcarousel = function(o) {
if (typeof o == 'string') {
var instance = $(this).data('jcarousel'), args = Array.prototype.slice.call(arguments, 1);
return instance[o].apply(instance, args);
} else
return this.each(function() {
$(this).data('jcarousel', new $jc(this, o));
});
};
// Default configuration properties.
var defaults = {
vertical: false,
rtl: false,
start: 1,
offset: 1,
size: null,
scroll: 3,
visible: null,
animation: 'normal',
easing: 'swing',
auto: 0,
wrap: null,
initCallback: null,
reloadCallback: null,
itemLoadCallback: null,
itemFirstInCallback: null,
itemFirstOutCallback: null,
itemLastInCallback: null,
itemLastOutCallback: null,
itemVisibleInCallback: null,
itemVisibleOutCallback: null,
buttonNextHTML: '<div></div>',
buttonPrevHTML: '<div></div>',
buttonNextEvent: 'click',
buttonPrevEvent: 'click',
buttonNextCallback: null,
buttonPrevCallback: null,
itemFallbackDimension: null
}, windowLoaded = false;
$(window).bind('load.jcarousel', function() { windowLoaded = true; })
/**
* The jCarousel object.
*
* @constructor
* @class jcarousel
* @param e {HTMLElement} The element to create the carousel for.
* @param o {Object} A set of key/value pairs to set as configuration properties.
* @cat Plugins/jCarousel
*/
$.jcarousel = function(e, o) {
this.options = $.extend({}, defaults, o || {});
this.locked = false;
this.container = null;
this.clip = null;
this.list = null;
this.buttonNext = null;
this.buttonPrev = null;
// Only set if not explicitly passed as option
if (!o || o.rtl === undefined)
this.options.rtl = ($(e).attr('dir') || $('html').attr('dir') || '').toLowerCase() == 'rtl';
this.wh = !this.options.vertical ? 'width' : 'height';
this.lt = !this.options.vertical ? (this.options.rtl ? 'right' : 'left') : 'top';
// Extract skin class
var skin = '', split = e.className.split(' ');
for (var i = 0; i < split.length; i++) {
if (split[i].indexOf('jcarousel-skin') != -1) {
$(e).removeClass(split[i]);
skin = split[i];
break;
}
}
if (e.nodeName.toUpperCase() == 'UL' || e.nodeName.toUpperCase() == 'OL') {
this.list = $(e);
this.container = this.list.parent();
if (this.container.hasClass('jcarousel-clip')) {
if (!this.container.parent().hasClass('jcarousel-container'))
this.container = this.container.wrap('<div></div>');
this.container = this.container.parent();
} else if (!this.container.hasClass('jcarousel-container'))
this.container = this.list.wrap('<div></div>').parent();
} else {
this.container = $(e);
this.list = this.container.find('ul,ol').eq(0);
}
if (skin != '' && this.container.parent()[0].className.indexOf('jcarousel-skin') == -1)
this.container.wrap('<div class=" '+ skin + '"></div>');
this.clip = this.list.parent();
if (!this.clip.length || !this.clip.hasClass('jcarousel-clip'))
this.clip = this.list.wrap('<div></div>').parent();
this.buttonNext = $('.jcarousel-next', this.container);
if (this.buttonNext.size() == 0 && this.options.buttonNextHTML != null)
this.buttonNext = this.clip.after(this.options.buttonNextHTML).next();
this.buttonNext.addClass(this.className('jcarousel-next'));
this.buttonPrev = $('.jcarousel-prev', this.container);
if (this.buttonPrev.size() == 0 && this.options.buttonPrevHTML != null)
this.buttonPrev = this.clip.after(this.options.buttonPrevHTML).next();
this.buttonPrev.addClass(this.className('jcarousel-prev'));
this.clip.addClass(this.className('jcarousel-clip')).css({
overflow: 'hidden',
position: 'relative'
});
this.list.addClass(this.className('jcarousel-list')).css({
overflow: 'hidden',
position: 'relative',
top: 0,
margin: 0,
padding: 0
}).css((this.options.rtl ? 'right' : 'left'), 0);
this.container.addClass(this.className('jcarousel-container')).css({
position: 'relative'
});
if (!this.options.vertical && this.options.rtl)
this.container.addClass('jcarousel-direction-rtl').attr('dir', 'rtl');
var di = this.options.visible != null ? Math.ceil(this.clipping() / this.options.visible) : null;
var li = this.list.children('li');
var self = this;
if (li.size() > 0) {
var wh = 0, i = this.options.offset;
li.each(function() {
self.format(this, i++);
wh += self.dimension(this, di);
});
this.list.css(this.wh, (wh + 100) + 'px');
// Only set if not explicitly passed as option
if (!o || o.size === undefined)
this.options.size = li.size();
}
// For whatever reason, .show() does not work in Safari...
this.container.css('display', 'block');
this.buttonNext.css('display', 'block');
this.buttonPrev.css('display', 'block');
this.funcNext = function() { self.next(); };
this.funcPrev = function() { self.prev(); };
this.funcResize = function() { self.reload(); };
if (this.options.initCallback != null)
this.options.initCallback(this, 'init');
if (!windowLoaded && $.browser.safari) {
this.buttons(false, false);
$(window).bind('load.jcarousel', function() { self.setup(); });
} else
this.setup();
};
// Create shortcut for internal use
var $jc = $.jcarousel;
$jc.fn = $jc.prototype = {
jcarousel: '0.2.5'
};
$jc.fn.extend = $jc.extend = $.extend;
$jc.fn.extend({
/**
* Setups the carousel.
*
* @method setup
* @return undefined
*/
setup: function() {
this.first = null;
this.last = null;
this.prevFirst = null;
this.prevLast = null;
this.animating = false;
this.timer = null;
this.tail = null;
this.inTail = false;
if (this.locked)
return;
this.list.css(this.lt, this.pos(this.options.offset) + 'px');
var p = this.pos(this.options.start);
this.prevFirst = this.prevLast = null;
this.animate(p, false);
$(window).unbind('resize.jcarousel', this.funcResize).bind('resize.jcarousel', this.funcResize);
},
/**
* Clears the list and resets the carousel.
*
* @method reset
* @return undefined
*/
reset: function() {
this.list.empty();
this.list.css(this.lt, '0px');
this.list.css(this.wh, '10px');
if (this.options.initCallback != null)
this.options.initCallback(this, 'reset');
this.setup();
},
/**
* Reloads the carousel and adjusts positions.
*
* @method reload
* @return undefined
*/
reload: function() {
if (this.tail != null && this.inTail)
this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) + this.tail);
this.tail = null;
this.inTail = false;
if (this.options.reloadCallback != null)
this.options.reloadCallback(this);
if (this.options.visible != null) {
var self = this;
var di = Math.ceil(this.clipping() / this.options.visible), wh = 0, lt = 0;
this.list.children('li').each(function(i) {
wh += self.dimension(this, di);
if (i + 1 < self.first)
lt = wh;
});
this.list.css(this.wh, wh + 'px');
this.list.css(this.lt, -lt + 'px');
}
this.scroll(this.first, false);
},
/**
* Locks the carousel.
*
* @method lock
* @return undefined
*/
lock: function() {
this.locked = true;
this.buttons();
},
/**
* Unlocks the carousel.
*
* @method unlock
* @return undefined
*/
unlock: function() {
this.locked = false;
this.buttons();
},
/**
* Sets the size of the carousel.
*
* @method size
* @return undefined
* @param s {Number} The size of the carousel.
*/
size: function(s) {
if (s != undefined) {
this.options.size = s;
if (!this.locked)
this.buttons();
}
return this.options.size;
},
/**
* Checks whether a list element exists for the given index (or index range).
*
* @method get
* @return bool
* @param i {Number} The index of the (first) element.
* @param i2 {Number} The index of the last element.
*/
has: function(i, i2) {
if (i2 == undefined || !i2)
i2 = i;
if (this.options.size !== null && i2 > this.options.size)
i2 = this.options.size;
for (var j = i; j <= i2; j++) {
var e = this.get(j);
if (!e.length || e.hasClass('jcarousel-item-placeholder'))
return false;
}
return true;
},
/**
* Returns a jQuery object with list element for the given index.
*
* @method get
* @return jQuery
* @param i {Number} The index of the element.
*/
get: function(i) {
return $('.jcarousel-item-' + i, this.list);
},
/**
* Adds an element for the given index to the list.
* If the element already exists, it updates the inner html.
* Returns the created element as jQuery object.
*
* @method add
* @return jQuery
* @param i {Number} The index of the element.
* @param s {String} The innerHTML of the element.
*/
add: function(i, s) {
var e = this.get(i), old = 0, n = $(s);
if (e.length == 0) {
var c, e = this.create(i), j = $jc.intval(i);
while (c = this.get(--j)) {
if (j <= 0 || c.length) {
j <= 0 ? this.list.prepend(e) : c.after(e);
break;
}
}
} else
old = this.dimension(e);
if (n.get(0).nodeName.toUpperCase() == 'LI') {
e.replaceWith(n);
e = n;
} else
e.empty().append(s);
this.format(e.removeClass(this.className('jcarousel-item-placeholder')), i);
var di = this.options.visible != null ? Math.ceil(this.clipping() / this.options.visible) : null;
var wh = this.dimension(e, di) - old;
if (i > 0 && i < this.first)
this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) - wh + 'px');
this.list.css(this.wh, $jc.intval(this.list.css(this.wh)) + wh + 'px');
return e;
},
/**
* Removes an element for the given index from the list.
*
* @method remove
* @return undefined
* @param i {Number} The index of the element.
*/
remove: function(i) {
var e = this.get(i);
// Check if item exists and is not currently visible
if (!e.length || (i >= this.first && i <= this.last))
return;
var d = this.dimension(e);
if (i < this.first)
this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) + d + 'px');
e.remove();
this.list.css(this.wh, $jc.intval(this.list.css(this.wh)) - d + 'px');
},
/**
* Moves the carousel forwards.
*
* @method next
* @return undefined
*/
next: function() {
this.stopAuto();
if (this.tail != null && !this.inTail)
this.scrollTail(false);
else
this.scroll(((this.options.wrap == 'both' || this.options.wrap == 'last') && this.options.size != null && this.last == this.options.size) ? 1 : this.first + this.options.scroll);
},
/**
* Moves the carousel backwards.
*
* @method prev
* @return undefined
*/
prev: function() {
this.stopAuto();
if (this.tail != null && this.inTail)
this.scrollTail(true);
else
this.scroll(((this.options.wrap == 'both' || this.options.wrap == 'first') && this.options.size != null && this.first == 1) ? this.options.size : this.first - this.options.scroll);
},
/**
* Scrolls the tail of the carousel.
*
* @method scrollTail
* @return undefined
* @param b {Boolean} Whether scroll the tail back or forward.
*/
scrollTail: function(b) {
if (this.locked || this.animating || !this.tail)
return;
var pos = $jc.intval(this.list.css(this.lt));
!b ? pos -= this.tail : pos += this.tail;
this.inTail = !b;
// Save for callbacks
this.prevFirst = this.first;
this.prevLast = this.last;
this.animate(pos);
},
/**
* Scrolls the carousel to a certain position.
*
* @method scroll
* @return undefined
* @param i {Number} The index of the element to scoll to.
* @param a {Boolean} Flag indicating whether to perform animation.
*/
scroll: function(i, a) {
if (this.locked || this.animating)
return;
this.animate(this.pos(i), a);
},
/**
* Prepares the carousel and return the position for a certian index.
*
* @method pos
* @return {Number}
* @param i {Number} The index of the element to scoll to.
*/
pos: function(i) {
var pos = $jc.intval(this.list.css(this.lt));
if (this.locked || this.animating)
return pos;
if (this.options.wrap != 'circular')
i = i < 1 ? 1 : (this.options.size && i > this.options.size ? this.options.size : i);
var back = this.first > i;
// Create placeholders, new list width/height
// and new list position
var f = this.options.wrap != 'circular' && this.first <= 1 ? 1 : this.first;
var c = back ? this.get(f) : this.get(this.last);
var j = back ? f : f - 1;
var e = null, l = 0, p = false, d = 0, g;
while (back ? --j >= i : ++j < i) {
e = this.get(j);
p = !e.length;
if (e.length == 0) {
e = this.create(j).addClass(this.className('jcarousel-item-placeholder'));
c[back ? 'before' : 'after' ](e);
if (this.first != null && this.options.wrap == 'circular' && this.options.size !== null && (j <= 0 || j > this.options.size)) {
g = this.get(this.index(j));
if (g.length)
e = this.add(j, g.clone(true));
}
}
c = e;
d = this.dimension(e);
if (p)
l += d;
if (this.first != null && (this.options.wrap == 'circular' || (j >= 1 && (this.options.size == null || j <= this.options.size))))
pos = back ? pos + d : pos - d;
}
// Calculate visible items
var clipping = this.clipping();
var cache = [];
var visible = 0, j = i, v = 0;
var c = this.get(i - 1);
while (++visible) {
e = this.get(j);
p = !e.length;
if (e.length == 0) {
e = this.create(j).addClass(this.className('jcarousel-item-placeholder'));
// This should only happen on a next scroll
c.length == 0 ? this.list.prepend(e) : c[back ? 'before' : 'after' ](e);
if (this.first != null && this.options.wrap == 'circular' && this.options.size !== null && (j <= 0 || j > this.options.size)) {
g = this.get(this.index(j));
if (g.length)
e = this.add(j, g.clone(true));
}
}
c = e;
var d = this.dimension(e);
if (d == 0) {
throw new Error('jCarousel: No width/height set for items. This will cause an infinite loop. Aborting...');
}
if (this.options.wrap != 'circular' && this.options.size !== null && j > this.options.size)
cache.push(e);
else if (p)
l += d;
v += d;
if (v >= clipping)
break;
j++;
}
// Remove out-of-range placeholders
for (var x = 0; x < cache.length; x++)
cache[x].remove();
// Resize list
if (l > 0) {
this.list.css(this.wh, this.dimension(this.list) + l + 'px');
if (back) {
pos -= l;
this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) - l + 'px');
}
}
// Calculate first and last item
var last = i + visible - 1;
if (this.options.wrap != 'circular' && this.options.size && last > this.options.size)
last = this.options.size;
if (j > last) {
visible = 0, j = last, v = 0;
while (++visible) {
var e = this.get(j--);
if (!e.length)
break;
v += this.dimension(e);
if (v >= clipping)
break;
}
}
var first = last - visible + 1;
if (this.options.wrap != 'circular' && first < 1)
first = 1;
if (this.inTail && back) {
pos += this.tail;
this.inTail = false;
}
this.tail = null;
if (this.options.wrap != 'circular' && last == this.options.size && (last - visible + 1) >= 1) {
var m = $jc.margin(this.get(last), !this.options.vertical ? 'marginRight' : 'marginBottom');
if ((v - m) > clipping)
this.tail = v - clipping - m;
}
// Adjust position
while (i-- > first)
pos += this.dimension(this.get(i));
// Save visible item range
this.prevFirst = this.first;
this.prevLast = this.last;
this.first = first;
this.last = last;
return pos;
},
/**
* Animates the carousel to a certain position.
*
* @method animate
* @return undefined
* @param p {Number} Position to scroll to.
* @param a {Boolean} Flag indicating whether to perform animation.
*/
animate: function(p, a) {
if (this.locked || this.animating)
return;
this.animating = true;
var self = this;
var scrolled = function() {
self.animating = false;
if (p == 0)
self.list.css(self.lt, 0);
if (self.options.wrap == 'circular' || self.options.wrap == 'both' || self.options.wrap == 'last' || self.options.size == null || self.last < self.options.size)
self.startAuto();
self.buttons();
self.notify('onAfterAnimation');
// This function removes items which are appended automatically for circulation.
// This prevents the list from growing infinitely.
if (self.options.wrap == 'circular' && self.options.size !== null)
for (var i = self.prevFirst; i <= self.prevLast; i++)
if (i !== null && !(i >= self.first && i <= self.last) && (i < 1 || i > self.options.size))
self.remove(i);
};
this.notify('onBeforeAnimation');
// Animate
if (!this.options.animation || a == false) {
this.list.css(this.lt, p + 'px');
scrolled();
} else {
var o = !this.options.vertical ? (this.options.rtl ? {'right': p} : {'left': p}) : {'top': p};
this.list.animate(o, this.options.animation, this.options.easing, scrolled);
}
},
/**
* Starts autoscrolling.
*
* @method auto
* @return undefined
* @param s {Number} Seconds to periodically autoscroll the content.
*/
startAuto: function(s) {
if (s != undefined)
this.options.auto = s;
if (this.options.auto == 0)
return this.stopAuto();
if (this.timer != null)
return;
var self = this;
this.timer = setTimeout(function() { self.next(); }, this.options.auto * 1000);
},
/**
* Stops autoscrolling.
*
* @method stopAuto
* @return undefined
*/
stopAuto: function() {
if (this.timer == null)
return;
clearTimeout(this.timer);
this.timer = null;
},
/**
* Sets the states of the prev/next buttons.
*
* @method buttons
* @return undefined
*/
buttons: function(n, p) {
if (n == undefined || n == null) {
var n = !this.locked && this.options.size !== 0 && ((this.options.wrap && this.options.wrap != 'first') || this.options.size == null || this.last < this.options.size);
if (!this.locked && (!this.options.wrap || this.options.wrap == 'first') && this.options.size != null && this.last >= this.options.size)
n = this.tail != null && !this.inTail;
}
if (p == undefined || p == null) {
var p = !this.locked && this.options.size !== 0 && ((this.options.wrap && this.options.wrap != 'last') || this.first > 1);
if (!this.locked && (!this.options.wrap || this.options.wrap == 'last') && this.options.size != null && this.first == 1)
p = this.tail != null && this.inTail;
}
var self = this;
this.buttonNext[n ? 'bind' : 'unbind'](this.options.buttonNextEvent + '.jcarousel', this.funcNext)[n ? 'removeClass' : 'addClass'](this.className('jcarousel-next-disabled')).attr('disabled', n ? false : true);
this.buttonPrev[p ? 'bind' : 'unbind'](this.options.buttonPrevEvent + '.jcarousel', this.funcPrev)[p ? 'removeClass' : 'addClass'](this.className('jcarousel-prev-disabled')).attr('disabled', p ? false : true);
if (this.options.buttonNextCallback != null && this.buttonNext.data('jcarouselstate') != n) {
this.buttonNext.each(function() { self.options.buttonNextCallback(self, this, n); }).data('jcarouselstate', n);
}
if (this.options.buttonPrevCallback != null && (this.buttonPrev.data('jcarouselstate') != p)) {
this.buttonPrev.each(function() { self.options.buttonPrevCallback(self, this, p); }).data('jcarouselstate', p);
}
},
/**
* Notify callback of a specified event.
*
* @method notify
* @return undefined
* @param evt {String} The event name
*/
notify: function(evt) {
var state = this.prevFirst == null ? 'init' : (this.prevFirst < this.first ? 'next' : 'prev');
// Load items
this.callback('itemLoadCallback', evt, state);
if (this.prevFirst !== this.first) {
this.callback('itemFirstInCallback', evt, state, this.first);
this.callback('itemFirstOutCallback', evt, state, this.prevFirst);
}
if (this.prevLast !== this.last) {
this.callback('itemLastInCallback', evt, state, this.last);
this.callback('itemLastOutCallback', evt, state, this.prevLast);
}
this.callback('itemVisibleInCallback', evt, state, this.first, this.last, this.prevFirst, this.prevLast);
this.callback('itemVisibleOutCallback', evt, state, this.prevFirst, this.prevLast, this.first, this.last);
},
callback: function(cb, evt, state, i1, i2, i3, i4) {
if (this.options[cb] == undefined || (typeof this.options[cb] != 'object' && evt != 'onAfterAnimation'))
return;
var callback = typeof this.options[cb] == 'object' ? this.options[cb][evt] : this.options[cb];
if (!$.isFunction(callback))
return;
var self = this;
if (i1 === undefined)
callback(self, state, evt);
else if (i2 === undefined)
this.get(i1).each(function() { callback(self, this, i1, state, evt); });
else {
for (var i = i1; i <= i2; i++)
if (i !== null && !(i >= i3 && i <= i4))
this.get(i).each(function() { callback(self, this, i, state, evt); });
}
},
create: function(i) {
return this.format('<li></li>', i);
},
format: function(e, i) {
var e = $(e), split = e.get(0).className.split(' ');
for (var j = 0; j < split.length; j++) {
if (split[j].indexOf('jcarousel-') != -1) {
e.removeClass(split[j]);
}
}
e.addClass(this.className('jcarousel-item')).addClass(this.className('jcarousel-item-' + i)).css({
'float': (this.options.rtl ? 'right' : 'left'),
'list-style': 'none'
}).attr('jcarouselindex', i);
return e;
},
className: function(c) {
return c + ' ' + c + (!this.options.vertical ? '-horizontal' : '-vertical');
},
dimension: function(e, d) {
var el = e.jquery != undefined ? e[0] : e;
var old = !this.options.vertical ?
(el.offsetWidth || $jc.intval(this.options.itemFallbackDimension)) + $jc.margin(el, 'marginLeft') + $jc.margin(el, 'marginRight') :
(el.offsetHeight || $jc.intval(this.options.itemFallbackDimension)) + $jc.margin(el, 'marginTop') + $jc.margin(el, 'marginBottom');
if (d == undefined || old == d)
return old;
var w = !this.options.vertical ?
d - $jc.margin(el, 'marginLeft') - $jc.margin(el, 'marginRight') :
d - $jc.margin(el, 'marginTop') - $jc.margin(el, 'marginBottom');
$(el).css(this.wh, w + 'px');
return this.dimension(el);
},
clipping: function() {
return !this.options.vertical ?
this.clip[0].offsetWidth - $jc.intval(this.clip.css('borderLeftWidth')) - $jc.intval(this.clip.css('borderRightWidth')) :
this.clip[0].offsetHeight - $jc.intval(this.clip.css('borderTopWidth')) - $jc.intval(this.clip.css('borderBottomWidth'));
},
index: function(i, s) {
if (s == undefined)
s = this.options.size;
return Math.round((((i-1) / s) - Math.floor((i-1) / s)) * s) + 1;
}
});
$jc.extend({
/**
* Gets/Sets the global default configuration properties.
*
* @method defaults
* @return {Object}
* @param d {Object} A set of key/value pairs to set as configuration properties.
*/
defaults: function(d) {
return $.extend(defaults, d || {});
},
margin: function(e, p) {
if (!e)
return 0;
var el = e.jquery != undefined ? e[0] : e;
if (p == 'marginRight' && $.browser.safari) {
var old = {'display': 'block', 'float': 'none', 'width': 'auto'}, oWidth, oWidth2;
$.swap(el, old, function() { oWidth = el.offsetWidth; });
old['marginRight'] = 0;
$.swap(el, old, function() { oWidth2 = el.offsetWidth; });
return oWidth2 - oWidth;
}
return $jc.intval($.css(el, p));
},
intval: function(v) {
v = parseInt(v);
return isNaN(v) ? 0 : v;
}
});
})(jQuery);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,3 @@
name = "Navigation Carousel"
description = "Adds a navigation carousel under the photo."
version = 4

View File

@ -0,0 +1,17 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<script type="text/javascript">
function changeaspectstate() {
var noresizecheck = document.getElementById('noresize');
var maintainaspectcheck = document.getElementById('maintainaspect');
changestate = noresizecheck.checked ? maintainaspectcheck.disabled=true : maintainaspectcheck.disabled=false;
}
window.onload=changeaspectstate;
</script>
<div id="g-admin-navcarousel">
<h2><?= t("Navigation carousel administration") ?></h2>
<h3><?= t("Notes:") ?></h3>
<p><?= t("There is a known bug with the positioning and scrolling of the album.<br />
If you are experiencing this bug then please enable the option 'Disable dynamic loading of thumbnails'.<br />
I am working on fixing this bug and will release an update as soon as possible.") ?></p>
<?= $form ?>
</div>

View File

@ -0,0 +1,202 @@
<?php defined("SYSPATH") or die("No direct script access.");
if (locales::is_rtl()) {
$rtl_support = "rtl: true,\n";
} else {
$rtl_support = "rtl: false,\n";
}
$carouselwidth = module::get_var("navcarousel", "carouselwidth", "600");
if ($carouselwidth == 0) {
$carouselwidth = "100%";
$containerwidth = "";
} else {
$carouselwidth = $carouselwidth ."px";
$containerwidth = ".jcarousel-skin-tango .jcarousel-container-horizontal {\n
width: ". $carouselwidth .";\n
}\n";
}
$thumbsize = module::get_var("navcarousel", "thumbsize", "50");
$showelements = module::get_var("navcarousel", "showelements", "7");
$childcount = $theme->item->parent()->viewable()->children_count();
$itemoffset = intval(floor($showelements / 2));
if ($childcount <= $showelements) {
$itemoffset = 1;
} else {
$itempos = $theme->item->parent()->get_position($theme->item);
$itemoffset = $itempos - $itemoffset;
if ($itemoffset < 1) {
$itemoffset = 1;
}
if (($itemoffset + $showelements) > $childcount) {
$itemoffset = $childcount - $showelements + 1;
}
}
if (module::get_var("navcarousel", "noajax", false)) {
$ajaxhandler = "";
} else {
$ajaxhandler = "itemLoadCallback: navcarousel_itemLoadCallback,\n";
}
if (module::get_var("navcarousel", "showondomready", false)) {
$onwinload = "";
} else {
$onwinload = "});\n
$(window).load(function () {\n";
}
echo "\n<!-- Navcaoursel -->
<style type=\"text/css\">\n
". $containerwidth ."
.jcarousel-skin-tango .jcarousel-clip-horizontal {\n
width: ". $carouselwidth .";\n
height: ". ($thumbsize + 25) ."px;\n
}\n
.jcarousel-skin-tango .jcarousel-item {\n
width: ". ($thumbsize + 25) ."px;\n
height: ". ($thumbsize + 25) ."px;\n
}\n
#navcarousel-loader {\n
height: ". ($thumbsize + 25) ."px;\n
}\n
.jcarousel-skin-tango .jcarousel-next-horizontal {
top: ". (intval(floor($thumbsize / 2.8))) ."px;
}
.jcarousel-skin-tango .jcarousel-prev-horizontal {
top: ". (intval(floor($thumbsize / 2.8))) ."px;
}
</style>\n
<script type=\"text/javascript\">\n
jQuery(document).ready(function() {\n
jQuery('#navcarousel').jcarousel({\n
". $ajaxhandler ."
itemFallbackDimension: ". ($thumbsize + 25) .",\n
start: ". $itemoffset .",\n
size: ". $childcount .",\n
visible: ". $showelements .",\n
". $rtl_support ."
scroll: ". module::get_var("navcarousel", "scrollsize", "7") ."\n
});\n
". $onwinload ."
$(\".jcarousel-prev-horizontal\").css(\"visibility\", \"visible\");\n
$(\".jcarousel-next-horizontal\").css(\"visibility\", \"visible\");\n
$(\"#navcarousel\").css(\"visibility\", \"visible\");\n
$(\"#navcarousel-wrapper\").css(\"background\", \"none\");\n
$(\"#navcarousel-wrapper\").css(\"float\", \"left\");\n
});\n
</script>\n
<!-- Navcaoursel -->";
$thumbsize = module::get_var("navcarousel", "thumbsize", "50");
$parent = $item->parent();
$item_counter = 0;
$item_offset = 0;
$maintain_aspect = module::get_var("navcarousel", "maintainaspect", false);
$no_resize = module::get_var("navcarousel", "noresize", false);
$no_ajax = module::get_var("navcarousel", "noajax", false);
?>
<div id="navcarousel-wrapper">
<ul id="navcarousel" class="jcarousel-skin-tango">
<?php
if (!$no_ajax) {
?>
</ul>
</div>
<script type="text/javascript">
function navcarousel_itemLoadCallback(carousel, state)
{
// Check if the requested items already exist
if (carousel.has(carousel.first, carousel.last)) {
return;
}
jQuery.get(
'<?= url::site("navcarousel/item/". $item->id) ?>',
{
first: carousel.first,
last: carousel.last
},
function(xml) {
navcarousel_itemAddCallback(carousel, carousel.first, carousel.last, xml);
},
'xml'
);
};
function navcarousel_itemAddCallback(carousel, first, last, xml)
{
// Set the size of the carousel
carousel.size(parseInt(jQuery('total', xml).text()));
jQuery('image', xml).each(function(i) {
carousel.add(first + i, navcarousel_getItemHTML(jQuery(this).text()));
});
};
function navcarousel_getItemHTML(url)
{
var thisurl='<?= $item->thumb_url() ?>';
var linkCollection = new Object;
<?php
}
$totalitems = ORM::factory("item")->where("parent_id", "=", $parent->id)->where("type", "=", "photo")->count_all();
foreach ($parent->viewable()->children() as $photo) {
if ($photo->is_album()) {
continue;
}
if ($photo->id == $item->id) {
$navcar_size_addition = 10;
} else {
$navcar_size_addition = 0;
}
if ($no_resize) {
$navcar_divsize = "style=\"width: ". ($thumbsize + $navcar_size_addition) ."px; height: ". ($thumbsize + $navcar_size_addition) ."px;\"";
if ($photo->width > $photo->height) {
$navcar_thumbsize = "height=\"". ($thumbsize + $navcar_size_addition) ."\"";
} else {
$navcar_thumbsize = "width=\"". ($thumbsize + $navcar_size_addition) ."\"";
}
} else {
$navcar_divsize = "";
if ($maintain_aspect) {
$navcar_thumbsize = photo::img_dimensions($photo->width, $photo->height, $thumbsize + $navcar_size_addition);
} else {
$navcar_thumbsize = "width=\"". ($thumbsize + $navcar_size_addition) ."\" height=\"". ($thumbsize + $navcar_size_addition) ."\"";
}
}
if ($no_ajax) {
if (module::get_var("navcarousel", "nomouseover", false)) {
$img_title = "";
} else {
$img_title = " title=\"". html::purify($photo->title)->for_html_attr() ." (". $parent->get_position($photo) . t("%position of %total", array("position" => "", "total" => $totalitems)) .")\"";
}
if ($item->id == $photo->id) {
echo "<li><div class=\"g-button ui-corner-all ui-icon-left ui-state-hover carousel-current\" ". $navcar_divsize ."><div style=\"width: 100%; height: 100%; overflow: hidden;\"><img src=\"". $photo->thumb_url() ."\" alt=\"". html::purify($photo->title)->for_html_attr() ."\"". $img_title ." ". $navcar_thumbsize ." /></div></div></li>\n";
} else {
echo "<li><div class=\"g-button ui-corner-all ui-icon-left ui-state-default carousel-thumbnail\" ". $navcar_divsize ."><div style=\"width: 100%; height: 100%; overflow: hidden;\"><a href=\"". $photo->abs_url() ."\"><img src=\"". $photo->thumb_url() ."\" alt=\"". html::purify($photo->title)->for_html_attr() ."\"". $img_title ." ". $navcar_thumbsize ." /></a></div></div></li>\n";
}
} else {
echo ("linkCollection['". $photo->thumb_url() ."'] = ['". $photo->abs_url() ."', '". html::purify($photo->title)->for_html_attr() ."', '". $parent->get_position($photo) ."', '". $navcar_thumbsize ."', '". $navcar_divsize ."'];\n");
}
}
if ($no_ajax) {
echo "
</ul>\n
</div>\n";
} else {
if (module::get_var("navcarousel", "nomouseover", false)) {
$img_title = "";
} else {
$img_title = " title=\"' + linkCollection[url][1] + ' (' + linkCollection[url][2] + '". t("%position of %total", array("position" => "", "total" => $totalitems)) .")\"";
}
?>
if (thisurl==url)
{
return '<div class="g-button ui-corner-all ui-icon-left ui-state-hover carousel-current" ' + linkCollection[url][4] + '><div style="width: 100%; height: 100%; overflow: hidden;"><img src="' + url + '" alt="' + linkCollection[url][1] + '"<?= $img_title ?> ' + linkCollection[url][3] + ' /></div></div>';
}
else
{
return '<div class="g-button ui-corner-all ui-icon-left ui-state-default carousel-thumbnail" ' + linkCollection[url][4] + '><div style="width: 100%; height: 100%; overflow: hidden;"><a href="' + linkCollection[url][0] + '"><img src="' + url + '" alt="' + linkCollection[url][1] + '"<?= $img_title ?> ' + linkCollection[url][3] + ' /></a></div></div>';
}
};
</script>
<?php
}

View File

@ -0,0 +1,157 @@
<?php defined("SYSPATH") or die("No direct script access.");/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 Admin_register_Controller extends Admin_Controller {
public function index() {
$count = ORM::factory("pending_user")
->where("state", "!=", 2)
->count_all();
if ($count == 0) {
site_status::clear("pending_user_registrations");
}
list ($form, $errors) = $this->_get_form();
print $this->_get_admin_view($form, $errors);
}
public function update() {
access::verify_csrf();
$post = new Validation($_POST);
$post->add_rules("policy", "required");
$post->add_rules("group", array($this, "passthru"));
$post->add_rules("email_verification", array($this, "passthru"));
// added Shad Laws, v2
$post->add_rules("admin_notify", array($this, "passthru"));
$post->add_rules("subject_prefix", array($this, "passthru"));
$group_list = array();
if ($post->validate()) {
module::set_var("registration", "policy", $post->policy);
module::set_var("registration", "default_group", $post->group);
module::set_var("registration", "email_verification", !empty($post->email_verification));
// added Shad Laws, v2
module::set_var("registration", "admin_notify", !empty($post->admin_notify));
module::set_var("registration", "subject_prefix", $post->subject_prefix);
message::success(t("Registration defaults have been updated."));
url::redirect("admin/register");
} else {
list ($form, $errors) = $this->_get_form();
$form = array_merge($form, $post->as_array());
$errors = array_merge($errors, $post->errors());
print $this->_get_admin_view($form, $errors);
}
}
// We need this validation callback in order to have the optional fields copied to
// validation array.
public function passthru($field) {
return true;
}
public function activate() {
access::verify_csrf();
$post = new Validation($_POST);
$post->add_rules("activate_users", "required");
$post->add_rules("activate", "alpha_numeric");
if ($post->validate()) {
$names = array();
if (!empty($post->activate)) {
foreach ($post->activate as $id) {
$user = register::create_new_user($id);
$names[] = $user->name;
}
message::success(t("Activated %users.", array("users" => implode(", ", $names))));
}
$count = ORM::factory("pending_user")
->where("state", "!=", 2)
->count_all();
if ($count == 0) {
site_status::clear("pending_user_registrations");
}
url::redirect("admin/register");
}
list ($form, $errors) = $this->_get_form();
$form = array_merge($form, $post->as_array());
$errors = array_merge($errors, $post->errors());
print $this->_get_admin_view($form, $errors);
}
private function _get_admin_view($form, $errors) {
$v = new Admin_View("admin.html");
$v->page_title = t("User registration");
$v->content = new View("admin_register.html");
$v->content->action = "admin/register/update";
$v->content->policy_list =
array("admin_only" => t("Only site administrators can create new user accounts."),
"visitor" =>
t("Visitors can create accounts and no administrator approval is required."),
"admin_approval" =>
t("Visitors can create accounts but administrator approval is required."));
$admin = identity::admin_user();
$v->content->disable_email =
empty($admin->email) || $form["policy"] == "admin_only" ? "disabled" : "";
if (empty($admin->email)) {
module::set_var("registration", "email_verification", false);
}
// below lines added Shad Laws, v2
$v->content->disable_admin_notify =
empty($admin->email) || $form["policy"] !== "admin_approval" ? "disabled" : "";
if (empty($admin->email)) {
module::set_var("registration", "admin_notify", false);
}
$v->content->group_list = array();
foreach (identity::groups() as $group) {
if ($group->id != identity::everybody()->id &&
$group->id != identity::registered_users()->id) {
$v->content->group_list[$group->id] = $group->name;
}
}
$hidden = array("name" => "csrf", "value" => access::csrf_token());
if (count($v->content->group_list)) {
$v->content->group_list =
array("" => t("Choose the default group")) + $v->content->group_list;
} else {
$hidden["group"] = "";
}
$v->content->hidden = $hidden;
$v->content->pending = ORM::factory("pending_user")->find_all();
$v->content->activate = "admin/register/activate";
$v->content->form = $form;
$v->content->errors = $errors;
return $v;
}
private function _get_form() {
$form = array("policy" => module::get_var("registration", "policy"),
"group" => module::get_var("registration", "default_group"),
"email_verification" => module::get_var("registration", "email_verification"),
// added Shad Laws, v2
"subject_prefix" => module::get_var("registration", "subject_prefix"),
"admin_notify" => module::get_var("registration", "admin_notify"));
$errors = array_fill_keys(array_keys($form), "");
return array($form, $errors);
}
}

View File

@ -0,0 +1,196 @@
<?php defined("SYSPATH") or die("No direct script access.");/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 register_Controller extends Controller {
const ALLOW_PRIVATE_GALLERY = true;
public function index() {
print $this->_get_form();
}
public function handler() {
access::verify_csrf();
$form = $this->_get_form();
$valid = $form->validate();
$name = $form->register_user->inputs["name"]->value;
if (register::check_user_name($name)) {
$form->register_user->inputs["name"]->add_error("in_use", 1);
$valid = false;
}
if ($valid) {
$pending_user = register::create_pending_request($form);
$policy = module::get_var("registration", "policy");
if ($policy == "visitor") {
if ($pending_user->state == 1) {
$user = register::create_new_user($pending_user->id);
Session::instance()->set("registration_first_usage");
auth::login($user);
Session::instance()->set("registration_first_usage", true);
$pending_user->delete();
} else {
$user = register::create_new_user($pending_user->id, true);
message::success(t("A confirmation email has been sent to your email address."));
}
} else if ($pending_user->state == 1) {
site_status::warning(
t("There are pending user registration. <a href=\"%url\">Review now!</a>",
// modified by Shad Laws, v2
// array("url" => html::mark_clean(url::site("admin/register")))),
array("url" => html::mark_clean(url::site("admin/register")), "locale" => module::get_var("gallery", "default_locale"))),
"pending_user_registrations");
message::success(t("Your registration request is awaiting administrator approval"));
// added by Shad Laws, v2
if (module::get_var("registration", "admin_notify") == 1) {
register::send_admin_notify($pending_user);
}
} else {
register::send_confirmation($pending_user);
message::success(t("A confirmation email has been sent to your email address."));
}
json::reply(array("result" => "success"));
} else {
json::reply(array("result" => "error", "html" => (string)$form));
}
}
public function confirm($hash) {
$pending_user = ORM::factory("pending_user")
->where("hash", "=", $hash)
->where("state", "=", 0)
->find();
if ($pending_user->loaded()) {
// @todo add a request date to the pending user table and check that it hasn't expired
$policy = module::get_var("registration", "policy");
$pending_user->state = 1;
$pending_user->save();
if ($policy == "vistor") {
$user = register::create_new_user($pending_user->id);
message::success(t("Your registration request has been approved"));
auth::login($user);
Session::instance()->set("registration_first_usage", true);
$pending_user->delete();
} else {
site_status::warning(
t("There are pending user registration. <a href=\"%url\">Review now!</a>",
// modified by Shad Laws, v2
// array("url" => html::mark_clean(url::site("admin/register")))),
array("url" => html::mark_clean(url::site("admin/register")), "locale" => module::get_var("gallery", "default_locale"))),
"pending_user_registrations");
message::success(t("Your registration request is awaiting administrator approval"));
// added by Shad Laws, v2
if (module::get_var("registration", "admin_notify") == 1) {
register::send_admin_notify($pending_user);
}
}
} else {
message::error(t("Your registration request is no longer valid, Please re-register."));
}
url::redirect(item::root()->abs_url());
}
public function first($hash) {
$pending_user = ORM::factory("pending_user")
->where("hash", "=", $hash)
->where("state", "=", 2)
->find();
if ($pending_user->loaded()) {
// @todo add a request date to the pending user table and check that it hasn't expired
$user = identity::lookup_user_by_name($pending_user->name);
if (!empty($user)) {
auth::login($user);
Session::instance()->set("registration_first_usage", true);
$pending_user->delete();
}
url::redirect(item::root()->abs_url());
} else {
message::warning(t("Your account is ready to use so please login."));
}
url::redirect(item::root()->abs_url());
}
public function welcome_message() {
$user = identity::active_user();
$password = substr(md5(rand()), 0, 8);
$user->password = $password;
$user->save();
$v = new View("register_welcome_message.html");
$v->user = $user;
$v->password = $password;
print $v;
}
public function change_password($id, $password) {
$user = user::lookup($id);
print $this->_get_change_password_form($user, $password);
}
private function _get_form() {
$minimum_length = module::get_var("user", "mininum_password_length", 5);
$form = new Forge("register/handler", "", "post", array("id" => "g-register-form"));
$group = $form->group("register_user")->label(t("Register user"));
$group->input("name")->label(t("Username"))->id("g-username")
->rules("required|length[1,32]")
->error_messages("in_use", t("There is already a user with that username"));
$group->input("full_name")->label(t("Full Name"))->id("g-fullname")
->rules("length[0, 255]");
$group->input("email")->label(t("Email"))->id("g-email")
->rules("required|valid_email|length[1,255]");
$group->input("email2")->label(t("Confirm email"))->id("g-email2")
->matches($group->email);
// modified by Shad Laws, v2
// $group->input("url")->label(t("URL"))->id("g-url")
$group->input("url")->label(t("URL")." (".t("optional").")")->id("g-url")
->rules("valid_url");
module::event("register_add_form", $form);
module::event("captcha_protect_form", $form);
$group->submit("")->value(t("Register"));
return $form;
}
/**
* Get the password change form. This code is copied from controllers/users.php. The
* difference is that as this is the first time logging on, the user might not have
* expected that they were going to have to enter the password displayed on the welcome
* page, and didn't make note of it. If we were using the standard change password dialog, the
* user would be screwed as there is no way to go back and get it. So with this dialog,
* we will provide the old password as a hidden field.
*/
private function _get_change_password_form($user, $password) {
$form = new Forge(
"users/change_password/$user->id", "", "post", array("id" => "g-change-password-user-form"));
$group = $form->group("change_password")->label(t("Change your password"));
$group->hidden("old_password")->value($password);
$group->password("password")->label(t("New password"))->id("g-password")
->error_messages("min_length", t("Your new password is too short"));
$group->script("")
->text(
'$("form").ready(function(){$(\'input[name="password"]\').user_password_strength();});');
$group->password("password2")->label(t("Confirm new password"))->id("g-password2")
->matches($group->password)
->error_messages("matches", t("The passwords you entered do not match"));
module::event("user_change_password_form", $user, $form);
$group->submit("")->value(t("Save"));
return $form;
}
}

View File

@ -0,0 +1 @@
#g-register-form { width: 350px; }

View File

@ -0,0 +1,138 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 register_Core {
private static $_states;
static function format_registration_state($state) {
if (empty(self::$_states)) {
$policy = module::get_var("registration", "policy");
$email_verification = module::get_var("registration", "email_verification");
$pending = $policy == "admin_only" || ($policy == "admin_approval" && !$email_verification);
self::$_states = array(t("Unconfirmed"),
$pending ? t("Pending") : t("Confirmed"),
t("Activated"));
}
return self::$_states[$state];
}
static function check_user_name($user_name) {
if (identity::lookup_user_by_name($user_name)) {
return true;
}
$user = ORM::factory("pending_user")
->where("name", "=", $user_name)
->find();
return $user->loaded();
}
static function send_user_created_confirmation($user, $requires_first=false) {
$message = new View("register_welcome.html");
$message->user = $user;
$message->site_url = $requires_first ? url::abs_site("register/first/{$user->hash}") :
url::abs_site("");
// added Shad Laws, v2
$message->subject_prefix = module::get_var("registration", "subject_prefix");
$message->locale = $user->locale; // as stored in pending_users table
$message->subject = t("Welcome", array("locale" => $message->locale));
// modified Shad Laws, v2
self::_sendemail($user->email, $message->subject_prefix.$message->subject, $message);
}
static function send_confirmation($user) {
$message = new View("confirm_registration.html");
$message->confirm_url = url::abs_site("register/confirm/{$user->hash}");
$message->user = $user;
// added Shad Laws, v2
$message->subject_prefix = module::get_var("registration", "subject_prefix");
$message->locale = $user->locale; // as stored in pending_users table
$message->subject = t("User registration confirmation", array("locale" => $message->locale));
// modified Shad Laws, v2
self::_sendemail($user->email, $message->subject_prefix.$message->subject, $message);
}
// function added Shad Laws, v2
static function send_admin_notify($user) {
$message = new View("register_admin_notify.html");
$message->admin_register_url = url::abs_site("admin/register");
$message->user = $user;
$message->subject_prefix = module::get_var("registration", "subject_prefix");
$message->locale = module::get_var("gallery", "default_locale"); // as Gallery default
$message->subject = t("New pending user registration", array("locale" => $message->locale));
self::_sendemail(module::get_var("gallery", "email_reply_to"), $message->subject_prefix.$message->subject, $message);
}
static function create_pending_request($form) {
$email_verification = module::get_var("registration", "email_verification");
$user = ORM::factory("pending_user");
$user->name = $form->register_user->inputs["name"]->value;
$user->full_name = $form->register_user->inputs["full_name"]->value;
$user->email = $form->register_user->inputs["email"]->value;
$user->url = $form->register_user->inputs["url"]->value;
$user->request_date = time();
// added by Shad Laws, v2
$user->locale = locales::locale_from_http_request() ? locales::locale_from_http_request() : module::get_var("gallery", "default_locale"); // sets default locale based on browser
if (!$email_verification) {
$user->state = 1;
}
$user->hash = md5(rand());
$user->save();
return $user;
}
static function create_new_user($id) {
$user = ORM::factory("pending_user", $id);
$password = md5(uniqid(mt_rand(), true));
$new_user = identity::create_user($user->name, $user->full_name, $password, $user->email);
$new_user->url = $user->url;
$new_user->admin = false;
$new_user->guest = false;
$new_user->save();
$group_id = module::get_var("registration", "default_group");
if ($group_id != null) {
$default_group = group::lookup($group_id);
if ($default_group != null) {
$default_group->add($new_user);
$default_group->save();
}
}
$user->hash = md5(uniqid(mt_rand(), true));
$user->state = 2;
$user->save();
self::send_user_created_confirmation($user, $password);
return $new_user;
}
private static function _sendemail($email, $subject, $message) {
Sendmail::factory()
->to($email)
->subject($subject)
->header("Mime-Version", "1.0")
// modified by Shad Laws, v2
->header("Content-type", "text/html; charset=utf-8")
->message($message->render())
->send();
}
}

View File

@ -0,0 +1,38 @@
<?php defined("SYSPATH") or die("No direct script access.");/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 register_event {
static function admin_menu($menu, $theme) {
$menu->get("settings_menu")
->append( Menu::factory("link")
->id("register_users")
->label(t("User registration"))
->url(url::site("admin/register")));
}
static function user_menu($menu, $theme) {
$user = identity::active_user();
if ($user->guest) {
$menu->append(Menu::factory("dialog")
->id("user_menu_register")
->css_id("g-register-menu")
->url(url::site("register"))
->label(t("Register")));
}
}
}

View File

@ -0,0 +1,70 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 register_installer {
static function install() {
$db = Database::instance();
$db->query("CREATE TABLE IF NOT EXISTS {pending_users} (
`id` int(9) NOT NULL auto_increment,
`name` varchar(32) NOT NULL,
`state` int(9) NOT NULL DEFAULT 0,
`full_name` varchar(255) NOT NULL,
`email` varchar(64) default NULL,
`hash` char(32) default NULL,
`url` varchar(255) default NULL,
`request_date` int(9) not NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY(`hash`, `state`),
UNIQUE KEY(`name`))
DEFAULT CHARSET=utf8;");
module::set_var("registration", "policy", "admin_only");
module::set_var("registration", "default_group", "");
module::set_var("registration", "email_verification", false);
// added Shad Laws, v2
module::set_var("registration", "admin_notify", false);
module::set_var("registration", "subject_prefix", "");
$db->query("ALTER TABLE {pending_users} ADD `locale` varchar(32) default NULL;");
// changed Shad Laws, v2
module::set_version("register", 2);
}
// function added Shad Laws, v2
static function upgrade() {
if (module::get_version("register") < 1) {
module::install("register");
}
if (is_null(module::get_var("registration", "admin_notify")) ||
is_null(module::get_var("registration", "subject_prefix")) ||
(module::get_version("register") < 2) ) {
module::set_var("registration", "admin_notify", false);
module::set_var("registration", "subject_prefix", "");
$db = Database::instance();
$db->query("ALTER TABLE {pending_users} ADD `locale` varchar(32) default NULL;");
}
module::set_version("register", 2);
}
static function uninstall() {
Database::instance()->query("DROP TABLE IF EXISTS {pending_users};");
// added Shad Laws, v2
module::clear_all_vars("registration");
}
}

View File

@ -0,0 +1,33 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 register_theme_Core {
static function page_bottom($theme) {
$session = Session::instance();
if ($session->get("registration_first_usage")) {
$session->delete("registration_first_usage");
return new View("register_welcome_message_loader.html");
}
}
// added Shad Laws, v2
static function head($theme) {
return $theme->css("register.css");
}
}

View File

@ -0,0 +1,21 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 Pending_user_Model extends ORM {
}

View File

@ -0,0 +1,7 @@
name = "User Registration"
description = "Allow guests to register as users."
version = 2
author_name = "revised to v2 by Shad Laws"
author_url = ""
info_url = "http://codex.gallery2.org/Gallery3:Modules:register"
discuss_url = "http://gallery.menalto.com/forum_module_register"

View File

@ -0,0 +1,98 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<script type="text/javascript">
$("#g-active-pending-users").ready(function() {
$(":radio[name='policy']").click(function (event) {
if ($(this).val() == "admin_only") {
$(":checkbox[name=email_verification]").attr("disabled", "disabled");
} else {
$(":checkbox[name=email_verification]").removeAttr("disabled");
}
if ($(this).val() !== "admin_approval") {
$(":checkbox[name=admin_notify]").attr("disabled", "disabled");
} else {
$(":checkbox[name=admin_notify]").removeAttr("disabled");
}
});
});
</script>
<div id="g-admin-register" class="g-block">
<h1><?= t("User registration administration") ?></h1>
<div id="g-registration-admin" class="g-block-content">
<?= form::open($action, array("method" => "post"), $hidden) ?>
<fieldset>
<legend><?= t("Confirmation policy") ?></legend>
<ul>
<? foreach ($policy_list as $policy => $text): ?>
<li>
<?= form::radio("policy", $policy, $policy == $form["policy"]) ?>
<?= form::label("policy", $text) ?>
</li>
<? endforeach ?>
<li>
<?= form::checkbox("email_verification", "true", !empty($form["email_verification"]), $disable_email) ?>
<?= form::label("email_verification", t("Require e-mail verification when a visitor creates an account")) ?>
</li>
<li>
<?= form::checkbox("admin_notify", "true", !empty($form["admin_notify"]), $disable_admin_notify) ?>
<?= form::label("admin_notify", t("Send a pending user registration notification email to the site 'reply to' email address")) ?>
</li>
<li>
<?= form::input("subject_prefix", $form["subject_prefix"]) ?>
<?= form::label("subject_prefix", t("Email subject line prefix, with trailing spaces as needed (e.g. '[Gallery3] ')")) ?>
</li>
<li>
<? if (!empty($group_list)): ?>
<label for="group" class="g-left"> <?= t("Default group: ") ?></label>
<?= form::dropdown(array("name" => "group"), $group_list, $form["group"]) ?></label>
<? else: ?>
<?= form::hidden("group", $form["group"]) ?></label>
<? endif ?>
</li>
<li>
<?= form::submit(array("id" => "g-registration-admin", "name" => "save", "class" => "submit", "style" => "clear:both!important"), t("Update")) ?>
</li>
</ul>
</fieldset>
</form>
</div>
<? if (count($pending)): ?>
<div id="g-activate-pending-users">
<?= form::open($activate, array("method" => "post"), $hidden) ?>
<fieldset>
<legend><?= t("Pending registrations") ?></legend>
<table>
<caption>
<?= t("To delete an unconfirmed registration, first activate it, then delete it from Users/Groups.") ?>
</caption>
<tr>
<th><?= t("Activate") ?></th>
<th><?= t("State") ?></th>
<th><?= t("User name") ?></th>
<th><?= t("Full name") ?></th>
<th><?= t("Email") ?></th>
<th><?= t("Registered") ?></th>
</tr>
<? foreach ($pending as $user): ?>
<tr class="<?= text::alternate("g-odd", "g-even") ?>">
<td>
<? if ($user->state != 2): ?>
<?= form::checkbox("activate[]", $user->id) ?>
<? else: ?>
&nbsp;
<? endif ?>
</td>
<td><?= register::format_registration_state($user->state) ?></td>
<td><?= t($user->name) ?></td>
<td><?= t($user->full_name) ?></td>
<td><a href="mailto:<?= t($user->email) ?>"><?= t($user->email) ?></a></td>
<td><?= t(gallery::date_time($user->request_date)) ?></td>
</tr>
<? endforeach ?>
</table>
<?= form::submit(array("id" => "g-registration-activate", "name" => "activate_users", "class" => "submit"), t("Activate selected")) ?>
</fieldset>
</form>
</div>
<? endif ?>
</div>

View File

@ -0,0 +1,18 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<html>
<head>
<title><?= ($subject_prefix.$subject) ?></title>
</head>
<body>
<h2><?= $subject ?></h2>
<p>
<?= t("Hello %name,", array("name" => $user->full_name ? $user->full_name : $user->name, "locale" => $locale)) ?>
</p>
<p>
<?= t("We received a request to to create a user with this email. If you made this request, you can confirm it by <a href=\"%confirm_url\">clicking this link</a>. If you didn't request this password reset, it's ok to ignore this mail.",
array("site_url" => html::mark_clean(url::base(false, "http")),
"confirm_url" => $confirm_url,
"locale" => $locale)) ?>
</p>
</body>
</html>

View File

@ -0,0 +1,15 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<html>
<head>
<title><?= ($subject_prefix.$subject) ?></title>
</head>
<body>
<h2><?= $subject ?></h2>
<p>
<?= t("There's a new pending user registration from %name.<br/>You can access the site by <a href=\"%site_url\">clicking this link</a>, after which you can review and approve this request.",
array("name" => $user->full_name ? $user->full_name : $user->name,
"locale" => $locale,
"site_url" => html::mark_clean($admin_register_url))) ?>
</p>
</body>
</html>

View File

@ -0,0 +1,17 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<html>
<head>
<title><?= ($subject_prefix.$subject) ?></title>
</head>
<body>
<h2><?= $subject ?></h2>
<p>
<?= t("Hello %name,", array("name" => $user->full_name ? $user->full_name : $user->name, "locale" => $locale)) ?>
</p>
<p>
<?= t("The user account you requested as been created.<br/>You can access the site by <a href=\"%site_url\">clicking this link</a> and you will be prompted to set your password at this point.",
array("site_url" => html::mark_clean($site_url),
"locale" => $locale)) ?>
</p>
</body>
</html>

View File

@ -0,0 +1,36 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<div id="g-welcome-message">
<h1 style="display: none">
<?= t("Welcome to Gallery 3!") ?>
</h1>
<p>
<h2>
<?= t("Welcome to Gallery3") ?>
</h2>
</p>
<p>
<?= t("First things first. You're logged in to the <b>%user_name</b> account. We have generated a password for you (%password). You should change your password to something that you'll remember.", array("user_name" => $user->name, "password" => $password)) ?>
</p>
<p>
<a href="<?= url::site("register/change_password/{$user->id}/$password") ?>"
title="<?= t("Edit your profile")->for_html_attr() ?>"
id="g-after-install-change-password-link"
class="g-button ui-state-default ui-corners-all">
<?= t("Change password now") ?>
</a>
<script type="text/javascript">
$("#g-after-install-change-password-link").gallery_dialog();
</script>
</p>
<p>
<?= t("Want to learn more? The <a href=\"%url\">Gallery website</a> has news and information about the Gallery project and community.", array("url" => "http://gallery.menalto.com")) ?>
</p>
<p>
<?= t("Having problems? There's lots of information in our <a href=\"%codex_url\">documentation site</a> or you can <a href=\"%forum_url\">ask for help in the forums!</a>", array("codex_url" => "http://codex.gallery2.org/Main_Page", "forum_url" => "http://gallery.menalto.com/forum")) ?>
</p>
</div>

View File

@ -0,0 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<span id="g-welcome-message-link"
title="<?= t("Welcome to Gallery 3")->for_html_attr() ?>"
href="<?= url::site("register/welcome_message") ?>"/>
<script type="text/javascript">
$(document).ready(function(){$("#g-welcome-message-link").gallery_dialog({immediate: true});});
</script>

View File

@ -0,0 +1,252 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 Admin_Tag_Cloud_Html5_Controller extends Admin_Controller {
public function index() {
// print screen from new form
$form = $this->_get_admin_form();
$this->_print_screen($form);
}
public function edit() {
access::verify_csrf();
$cfg = $this->_get_config();
$form = $this->_get_admin_form();
if ($form->validate()) {
if ($form->general->reset_defaults->value) {
// reset all to defaults, redirect with message
module::install("tag_cloud_html5");
message::success(t("Tag cloud options reset successfully"));
url::redirect("admin/tag_cloud_html5");
}
// save the new inputs
module::set_var("tag_cloud_html5", "show_wholecloud_link", ($form->general->show_wholecloud_link->value == 1));
module::set_var("tag_cloud_html5", "show_add_tag_form", ($form->general->show_add_tag_form->value == 1));
module::set_var("tag_cloud_html5", "show_wholecloud_list", ($form->general->show_wholecloud_list->value == 1));
foreach ($cfg['groups'] as $groupname => $grouptext) {
module::set_var("tag_cloud_html5", "maxtags".$groupname, $form->{"size".$groupname}->{"maxtags".$groupname}->value);
module::set_var("tag_cloud_html5", "width".$groupname, $form->{"size".$groupname}->{"width".$groupname}->value);
module::set_var("tag_cloud_html5", "height".$groupname, $form->{"size".$groupname}->{"height".$groupname}->value);
$optionsarray = array();
// group size
$optionsarray['shape'] = $form->{"size".$groupname}->{"shape".$groupname}->value;
$optionsarray['zoom'] = $form->{"size".$groupname}->{"zoom".$groupname}->value;
$optionsarray['stretchX'] = $form->{"size".$groupname}->{"stretchX".$groupname}->value;
$optionsarray['stretchY'] = $form->{"size".$groupname}->{"stretchY".$groupname}->value;
// group motion
$optionsarray['maxSpeed'] = $form->{"motion".$groupname}->{"maxSpeed".$groupname}->value;
$optionsarray['minSpeed'] = $form->{"motion".$groupname}->{"minSpeed".$groupname}->value;
$optionsarray['deadZone'] = $form->{"motion".$groupname}->{"deadZone".$groupname}->value;
$optionsarray['decel'] = $form->{"motion".$groupname}->{"decel".$groupname}->value;
$optionsarray['initial'] = array($form->{"motion".$groupname}->{"initialX".$groupname}->value, $form->{"motion".$groupname}->{"initialY".$groupname}->value);
$optionsarray['maxInputZone'] = $form->{"motion".$groupname}->{"maxInputZone".$groupname}->value;
// group select
$optionsarray['outlineMethod'] = $form->{"select".$groupname}->{"outlineMethod".$groupname}->value;
$optionsarray['outlineOffset'] = $form->{"select".$groupname}->{"outlineOffset".$groupname}->value;
$optionsarray['outlineColour'] = $form->{"select".$groupname}->{"outlineColour".$groupname}->value;
$optionsarray['frontSelect'] = ($form->{"select".$groupname}->{"frontSelect".$groupname}->value == 1);
// group appearance
$optionsarray['textHeight'] = $form->{"appearance".$groupname}->{"textHeight".$groupname}->value;
$optionsarray['textColour'] = $form->{"appearance".$groupname}->{"textColour".$groupname}->value;
$optionsarray['textFont'] = $form->{"appearance".$groupname}->{"textFont".$groupname}->value;
$optionsarray['depth'] = $form->{"appearance".$groupname}->{"depth".$groupname}->value;
// options that are not explicitly defined in admin menu
$optionsarray['wheelZoom'] = false; // otherwise scrolling through the page screws everything up (was a problem in v1)
$optionsarray['initialDecel'] = true; // this was an option in v4, but it's sorta useless - use minSpeed for a related but better effect
$optionsarray['physModel'] = true; // this is the big enhancement for v5, and is a major modification that I did to TagCanvas
switch ($optionsarray['shape']) {
case "hcylinder":
// keep it horizontal - lock x-axis rotation
$optionsarray['lock'] = "x";
break;
case "vcylinder":
// keep it vertical - lock y-axis rotation
$optionsarray['lock'] = "y";
break;
default:
// do not lock either axis
$optionsarray['lock'] = "";
}
module::set_var("tag_cloud_html5", "options".$groupname, json_encode($optionsarray));
}
// all done; redirect with message
message::success(t("Tag cloud options updated successfully"));
url::redirect("admin/tag_cloud_html5");
}
// not valid - print screen from existing form
$this->_print_screen($form);
}
private function _get_config() {
// these define the two variable name groups, along with their labels which are always shown with t() for i18n.
$cfg['groups'] = array("_sidebar"=>t("Sidebar"), "_wholecloud"=>t("Whole cloud"));
// this defines the separator that's used between the group name and the attribute, and is *not* put through t().
$cfg['sep'] = " : ";
// this is used in the labels of the width/height parameters
$cfg['size'] = array("_sidebar"=>t("as fraction of sidebar width, e.g. 'g-block-content' class"), "_wholecloud"=>t("as fraction of browser window height"));
return $cfg;
}
private function _print_screen($form) {
// this part is a bit of a hack, but Forge doesn't seem to allow set_attr() for groups.
$form = $form->render();
$form = preg_replace("/<fieldset>/","<fieldset class=\"g-tag-cloud-html5-admin-form-top\">",$form,1);
$form = preg_replace("/<fieldset>/","<fieldset class=\"g-tag-cloud-html5-admin-form-left\">",$form,4);
$form = preg_replace("/<fieldset>/","<fieldset class=\"g-tag-cloud-html5-admin-form-right\">",$form,4);
$view = new Admin_View("admin.html");
$view->content = new View("admin_tag_cloud_html5.html");
$view->content->form = $form;
print $view;
}
private function _get_admin_form() {
$cfg = $this->_get_config();
$sep = $cfg['sep'];
// Make the main form. This form has *nine* groups: general, then size, motion, select, and appearance for _sidebar and _wholecloud.
$form = new Forge("admin/tag_cloud_html5/edit", "", "post", array("id" => "g-tag-cloud-html5-admin-form"));
// group general
$group_general = $form->group("general")->label(t("General"))->set_attr("id","g-tag-cloud-html5-admin-form-general");
$group_general->checkbox("reset_defaults")
->label(t("Reset all to default values"))
->checked(false);
$group_general->checkbox("show_wholecloud_link")
->label(t("Show 'View whole cloud' link in sidebar"))
->checked(module::get_var("tag_cloud_html5", "show_wholecloud_link", null));
$group_general->checkbox("show_add_tag_form")
->label(t("Show 'Add tag to album' form in sidebar (when permitted and applicable)"))
->checked(module::get_var("tag_cloud_html5", "show_add_tag_form", null));
$group_general->checkbox("show_wholecloud_list")
->label(t("Show inline tag list under cloud on 'View whole cloud' page")." {hideTags}")
->checked(module::get_var("tag_cloud_html5", "show_wholecloud_list", null));
foreach ($cfg['groups'] as $groupname => $grouptext) {
$maxtags = strval(module::get_var("tag_cloud_html5", "maxtags".$groupname, null));
$width = strval(module::get_var("tag_cloud_html5", "width".$groupname, null));
$height = strval(module::get_var("tag_cloud_html5", "height".$groupname, null));
$options = json_decode(module::get_var("tag_cloud_html5", "options".$groupname, null),true);
// group size/shape
${"group_size".$groupname} = $form->group("size".$groupname)->label(t("Size and shape").$sep.$grouptext);
${"group_size".$groupname}->input("maxtags".$groupname)
->label(t("maximum tags shown"))
->value($maxtags)
->rules("required|numrange[0]");
${"group_size".$groupname}->input("width".$groupname)
->label(t("width")." (".$cfg['size'][$groupname].")")
->value($width)
->rules("required|numrange[0]");
${"group_size".$groupname}->input("height".$groupname)
->label(t("height")." (".$cfg['size'][$groupname].")")
->value($height)
->rules("required|numrange[0]");
${"group_size".$groupname}->dropdown("shape".$groupname)
->label(t("shape of cloud")." {shape,lock}")
->options(array("sphere"=>t("sphere"),"hcylinder"=>t("horizontal cylinder"),"vcylinder"=>t("vertical cylinder")))
->selected($options['shape']);
${"group_size".$groupname}->input("zoom".$groupname)
->label(t("zoom (<1.0 is zoom out, >1.0 is zoom in)")." {zoom}")
->value($options['zoom'])
->rules("required|numrange[0]");
${"group_size".$groupname}->input("stretchX".$groupname)
->label(t("x-axis stretch factor (<1.0 squishes, >1.0 stretches)")." {stretchX}")
->value($options['stretchX'])
->rules("required|numrange[0]");
${"group_size".$groupname}->input("stretchY".$groupname)
->label(t("y-axis stretch factor (<1.0 squishes, >1.0 stretches)")." {stretchY}")
->value($options['stretchY'])
->rules("required|numrange[0]");
// group motion
${"group_motion".$groupname} = $form->group("motion".$groupname)->label(t("Motion").$sep.$grouptext);
${"group_motion".$groupname}->input("maxSpeed".$groupname)
->label(t("max speed (typically 0.01-0.20)")." {maxSpeed}")
->value($options['maxSpeed'])
->rules("required|numrange[0]");
${"group_motion".$groupname}->input("minSpeed".$groupname)
->label(t("no mouseover speed (typically 0.00-0.01)")." {minSpeed}")
->value($options['minSpeed'])
->rules("required|numrange[0]");
${"group_motion".$groupname}->input("deadZone".$groupname)
->label(t("dead zone size (0.0-1.0 - 0.0 is none and 1.0 is entire cloud)")." {deadZone}")
->value($options['deadZone'])
->rules("required|numrange[0,1]");
${"group_motion".$groupname}->input("decel".$groupname)
->label(t("inertia (0.0-1.0 - 0.0 changes velocity instantly and 1.0 never changes)")." {decel}")
->value($options['decel'])
->rules("required|numrange[0,1]");
${"group_motion".$groupname}->input("initialX".$groupname)
->label(t("initial horizontal speed (between +/-1.0, as fraction of max speed)")." {initial}")
->value($options['initial'][0])
->rules("required|numrange[-1,1]");
${"group_motion".$groupname}->input("initialY".$groupname)
->label(t("initial vertical speed (between +/-1.0, as fraction of max speed)")." {initial}")
->value($options['initial'][1])
->rules("required|numrange[-1,1]");
${"group_motion".$groupname}->input("maxInputZone".$groupname)
->label(t("mouseover region beyond cloud (as fraction of cloud - 0.0 is tight around cloud)")." {maxInputZone}")
->value($options['maxInputZone'])
->rules("required|numrange[0]");
// group select
${"group_select".$groupname} = $form->group("select".$groupname)->label(t("Tag selection").$sep.$grouptext);
${"group_select".$groupname}->dropdown("outlineMethod".$groupname)
->label(t("change of display for selected tag")." {outlineMethod}")
->options(array("colour"=>t("change text color"),"outline"=>t("add outline around text"),"block"=>t("add block behind text")))
->selected($options['outlineMethod']);
${"group_select".$groupname}->input("outlineOffset".$groupname)
->label(t("mouseover region around tag text (in pixels - 0 is tight around text)")." {outlineOffset}")
->value($options['outlineOffset'])
->rules("required|numrange[0]");
${"group_select".$groupname}->input("outlineColour".$groupname)
->label(t("color used for change of display (as #hhhhhh)")." {outlineColour}")
->value($options['outlineColour'])
->rules('required|color');
${"group_select".$groupname}->checkbox("frontSelect".$groupname)
->label(t("only allow tags in front to be selected")." {frontSelect}")
->checked($options['frontSelect']);
// group appearance
${"group_appearance".$groupname} = $form->group("appearance".$groupname)->label(t("Appearance").$sep.$grouptext);
${"group_appearance".$groupname}->input("textHeight".$groupname)
->label(t("text height (in pixels)")." {textHeight}")
->value($options['textHeight'])
->rules("required|numrange[0]");
${"group_appearance".$groupname}->input("textColour".$groupname)
->label(t("text color (as #hhhhhh, or empty to use theme color)")." {textColour}")
->value($options['textColour'])
->rules('color');
${"group_appearance".$groupname}->input("textFont".$groupname)
->label(t("text font family (empty to use theme font family)")." {textFont}")
->value($options['textFont'])
->rules("length[0,60]");
${"group_appearance".$groupname}->input("depth".$groupname)
->label(t("depth/perspective of cloud (0.0-1.0 - 0.0 is none and >0.9 gets strange)")." {depth}")
->value($options['depth'])
->rules("required|numrange[0,1]");
}
$form->submit("")->value(t("Save"));
return $form;
}
}

View File

@ -0,0 +1,114 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 Tag_Cloud_Controller extends Controller {
public function index() {
// Require view permission for the root album for security purposes.
$album = ORM::factory("item", 1);
access::required("view", $album);
// Get settings
$options = module::get_var("tag_cloud_html5", "options_wholecloud", null);
$maxtags = module::get_var("tag_cloud_html5", "maxtags_wholecloud", null);
$width = module::get_var("tag_cloud_html5", "width_wholecloud", null);
$height = module::get_var("tag_cloud_html5", "height_wholecloud", null);
$options = json_decode($options, true);
$options['hideTags'] = !module::get_var("tag_cloud_html5", "show_wholecloud_list", true);
$options = json_encode($options);
// Set up and display the actual page.
$template = new Theme_View("page.html", "other", "Tag cloud");
$template->content = new View("tag_cloud_html5_page.html");
$template->content->title = t("Tag cloud");
$template->content->cloud = tag::cloud($maxtags);
$template->content->options = $options;
$template->content->width = $width;
$template->content->height = $height;
// Display the page.
print $template;
}
public function embed() {
/**
* This is used to embed the tag cloud in other things. New in version 7.
*
* It expects the url to be in the form:
* tag_cloud/embed/optionsbase/option1/value1/option2/value2/.../optionN/valueN
* Where:
* optionsbase = "sidebar" or "wholecloud" (takes settings from this config)
* optionX = option name (either "maxtags" or any of the TagCanvas parameters - no name verification performed!)
* valueX = value of option (no value verification performed here!)
* Here's how the tag cloud is built:
* 1. Load "maxtags" and "options" variables for optionbase (as defined in admin menu or admin/advanced variables)
* Note: width and height are ignored, and the add tag form, wholecloud link, and inline tags are not shown.
* 2. Use option/value pairs to override and/or append those loaded above.
* 3. Build tag cloud, using 100% of the size from its parent.
* Correspondingly, the optionsbase is required, but the options and values are not.
*/
// Require view permission for the root album for security purposes.
$album = ORM::factory("item", 1);
access::required("view", $album);
// get the function arguments
$args = func_get_args();
// get/check the number of arguments - must be odd
$countargs = count($args);
if ($countargs % 2 == 0) {
return;
}
// get/check the first argument - must be sidebar or wholecloud
$optionsbase = $args[0];
if (!(in_array($optionsbase, array("sidebar", "wholecloud")))) {
return;
}
// get and override/append options/values
$maxtags = module::get_var("tag_cloud_html5", "maxtags_".$optionsbase, null);
$options = module::get_var("tag_cloud_html5", "options_".$optionsbase, null);
$options = json_decode($options, true);
for ($i = 0; $i < ($countargs-1)/2; $i++) {
$option = $args[2*$i+1];
$value = $args[2*$i+2];
if ($option == "maxtags") {
// assign to maxtags
$maxtags = $value;
} elseif (substr($option,-6) == 'Colour') {
// assign to options with a hash in front
$options[$option] = '#'.$value;
} else {
// assign to options
$options[$option] = $value;
}
}
$options = json_encode($options);
// Set up and display the actual page.
$template = new View("tag_cloud_html5_embed.html");
$template->cloud = tag::cloud($maxtags);
$template->options = $options;
// Display the page.
print $template;
}
}

View File

@ -0,0 +1,17 @@
#g-content fieldset {
display: block;
}
#g-content fieldset.g-tag-cloud-html5-admin-form-top {
width: 80%;
clear: both;
}
#g-content fieldset.g-tag-cloud-html5-admin-form-left {
width: 45%;
float: left;
clear: left;
margin-right: 2%
}
#g-content fieldset.g-tag-cloud-html5-admin-form-right {
width: 45%;
clear: right;
}

View File

@ -0,0 +1,106 @@
/* Tag cloud - sidebar ~~~~~~~~~~~~~~~~~~~~~~~ */
/* comment out this first block to make the inline tags appear if the cloud doesn't load */
#g-tag-cloud-html5-tags {
display: none;
}
#g-tag-cloud-html5-tags ul {
text-align: justify;
}
#g-tag-cloud-html5-tags ul li {
display: inline;
text-align: justify;
}
#g-tag-cloud-html5-tags ul li a {
text-decoration: none;
}
#g-tag-cloud-html5-tags ul li span {
display: none;
}
#g-tag-cloud-html5-page ul li a:hover {
text-decoration: underline;
}
/* Tag cloud - whole cloud page ~~~~~~~~~~~~~~~~~~~~~~~ */
#g-tag-cloud-html5-page-canvas {
display: block;
margin: 0 auto;
}
#g-tag-cloud-html5-page-tags ul {
font-size: 1.2em;
text-align: justify;
}
#g-tag-cloud-html5-page-tags ul li {
display: inline;
line-height: 1.5em;
text-align: justify;
}
#g-tag-cloud-html5-page-tags ul li a {
text-decoration: none;
}
#g-tag-cloud-html5-page-tags ul li span {
display: none;
}
#g-tag-cloud-html5-page-tags ul li.size0 a {
color: #9cf;
font-size: 70%;
font-weight: 100;
}
#g-tag-cloud-html5-page-tags ul li.size1 a {
color: #9cf;
font-size: 80%;
font-weight: 100;
}
#g-tag-cloud-html5-page-tags ul li.size2 a {
color: #69f;
font-size: 90%;
font-weight: 300;
}
#g-tag-cloud-html5-page-tags ul li.size3 a {
color: #69c;
font-size: 100%;
font-weight: 500;
}
#g-tag-cloud-html5-page-tags ul li.size4 a {
color: #369;
font-size: 110%;
font-weight: 700;
}
#g-tag-cloud-html5-page-tags ul li.size5 a {
color: #0e2b52;
font-size: 120%;
font-weight: 900;
}
#g-tag-cloud-html5-page-tags ul li.size6 a {
color: #0e2b52;
font-size: 130%;
font-weight: 900;
}
#g-tag-cloud-html5-page-tags ul li.size7 a {
color: #0e2b52;
font-size: 140%;
font-weight: 900;
}
#g-tag-cloud-html5-page-tags ul li a:hover {
color: #f30;
text-decoration: underline;
}

View File

@ -0,0 +1,67 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 tag_cloud_html5_block {
static function get_site_list() {
return array(
"tag_cloud_html5_site" => (t("Tag cloud")." HTML5"));
}
static function get($block_id, $theme) {
$block = "";
switch ($block_id) {
case "tag_cloud_html5_site":
// load settings
$options = module::get_var("tag_cloud_html5", "options_sidebar", null);
$maxtags = module::get_var("tag_cloud_html5", "maxtags_sidebar", null);
$showlink = module::get_var("tag_cloud_html5", "show_wholecloud_link", null);
$showaddtag = module::get_var("tag_cloud_html5", "show_add_tag_form", null);
$width = module::get_var("tag_cloud_html5", "width_sidebar", null);
$height = module::get_var("tag_cloud_html5", "height_sidebar", null);
// make the block
$block = new Block();
$block->css_id = "g-tag";
$block->title = t("Tag cloud");
$block->content = new View("tag_cloud_html5_block.html");
$block->content->cloud = tag::cloud($maxtags);
$block->content->options = $options;
$block->content->width = $width;
$block->content->height = $height;
// add the 'View whole cloud' link if needed
if ($showlink) {
$block->content->wholecloud_link = "<a href=".url::site("tag_cloud/").">".t("View whole cloud")."</a>";
} else {
$block->content->wholecloud_link = "";
}
// add the 'Add tag' form if needed
if ($theme->item() && $theme->page_subtype() != "tag" && access::can("edit", $theme->item()) && $showaddtag) {
$controller = new Tags_Controller();
$block->content->form = tag::get_add_form($theme->item());
} else {
$block->content->form = "";
}
break;
}
return $block;
}
}

View File

@ -0,0 +1,28 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 tag_cloud_html5_event_Core {
static function admin_menu($menu, $theme) {
$menu->get("settings_menu")
->append(Menu::factory("link")
->id("tag_cloud_html5")
->label(t("Tag cloud")." HTML5")
->url(url::site("admin/tag_cloud_html5")));
}
}

View File

@ -0,0 +1,177 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 tag_cloud_html5_installer {
static function install() {
// clear and reset default values. this is also called in the admin menu for
// 'reset all to default values' and if the upgrader sees variables missing.
module::clear_all_vars("tag_cloud_html5");
module::set_var("tag_cloud_html5", "show_wholecloud_link", true);
module::set_var("tag_cloud_html5", "show_add_tag_form", true);
module::set_var("tag_cloud_html5", "show_wholecloud_list", true);
module::set_var("tag_cloud_html5", "maxtags_sidebar", 30);
module::set_var("tag_cloud_html5", "width_sidebar", 1.00);
module::set_var("tag_cloud_html5", "height_sidebar", 0.8);
module::set_var("tag_cloud_html5", "maxtags_wholecloud", 500);
module::set_var("tag_cloud_html5", "width_wholecloud", 0.95);
module::set_var("tag_cloud_html5", "height_wholecloud", 0.75);
module::set_var("tag_cloud_html5", "options_sidebar", json_encode(array(
"maxSpeed" => 0.05,
"deadZone" => 0.25,
"initial" => array(0.8,-0.3),
"initialDecel" => true,
"zoom" => 1.25,
"depth" => 0.5,
"outlineMethod" => "colour",
"outlineOffset" => 8,
"outlineColour" => "#eeeeee",
"textColour" => "",
"textFont" => "",
"textHeight" => 12,
"frontSelect" => true,
"wheelZoom" => false,
"shape" => "sphere",
"lock" => "",
"stretchX" => 1.0,
"stretchY" => 1.0,
"decel" => 0.92,
"physModel" => true,
"maxInputZone" => 0.25,
"minSpeed" => 0.002
)));
module::set_var("tag_cloud_html5", "options_wholecloud", json_encode(array(
"maxSpeed" => 0.05,
"deadZone" => 0.25,
"initial" => array(0.8,-0.3),
"initialDecel" => true,
"zoom" => 1.25,
"depth" => 0.5,
"outlineMethod" => "colour",
"outlineOffset" => 8,
"outlineColour" => "#eeeeee",
"textColour" => "",
"textFont" => "",
"textHeight" => 13,
"frontSelect" => true,
"wheelZoom" => false,
"shape" => "sphere",
"lock" => "",
"stretchX" => 1.0,
"stretchY" => 1.0,
"decel" => 0.92,
"physModel" => true,
"maxInputZone" => 0.15,
"minSpeed" => 0.002
)));
module::set_version("tag_cloud_html5", 7);
}
static function upgrade() {
if (is_null(module::get_var("tag_cloud_html5", "options_sidebar")) ||
is_null(module::get_var("tag_cloud_html5", "options_wholecloud")) ||
(module::get_version("tag_cloud_html5") < 1) ) {
module::install("tag_cloud_html5");
}
if (module::get_version("tag_cloud_html5") < 2) {
// added wheelZoom, which is not accessible from admin menu
$options = json_decode(module::get_var("tag_cloud_html5", "options_sidebar"),true);
$options["wheelZoom"] = false;
module::set_var("tag_cloud_html5", "options_sidebar", json_encode($options));
$options = json_decode(module::get_var("tag_cloud_html5", "options_wholecloud"),true);
$options["wheelZoom"] = false;
module::set_var("tag_cloud_html5", "options_wholecloud", json_encode($options));
}
if (module::get_version("tag_cloud_html5") < 3) {
// added deadZone, initial, and initialDecel
module::set_var("tag_cloud_html5", "show_add_tag_form", true);
$options = json_decode(module::get_var("tag_cloud_html5", "options_sidebar"),true);
$options["deadZone"] = 0.25;
$options["initial"] = array(0.8,-0.3);
$options["initialDecel"] = true;
module::set_var("tag_cloud_html5", "options_sidebar", json_encode($options));
$options = json_decode(module::get_var("tag_cloud_html5", "options_wholecloud"),true);
$options["deadZone"] = 0.25;
$options["initial"] = array(0.8,-0.3);
$options["initialDecel"] = true;
module::set_var("tag_cloud_html5", "options_wholecloud", json_encode($options));
}
if (module::get_version("tag_cloud_html5") < 4) {
// added height_sidebar, then scaled back zoom and textHeight for consistency
module::set_var("tag_cloud_html5", "height_sidebar", 0.8);
$options = json_decode(module::get_var("tag_cloud_html5", "options_sidebar"),true);
$options["zoom"] = $options["zoom"] / 0.8;
$options["textHeight"] = $options["textHeight"] * 0.8;
module::set_var("tag_cloud_html5", "options_sidebar", json_encode($options));
}
if (module::get_version("tag_cloud_html5") < 5) {
// added lots of options that are on admin menu
// added physModel, lock, and initialDecel as options not on admin menu
// (previously initialDecel was on menu, so reset here)
module::set_var("tag_cloud_html5", "width_sidebar", 1.00);
module::set_var("tag_cloud_html5", "width_wholecloud", 0.95);
module::set_var("tag_cloud_html5", "height_wholecloud", 0.75);
$options = json_decode(module::get_var("tag_cloud_html5", "options_sidebar"),true);
$options["deadZone"] = $options["deadZone"];
$options["shape"] = "sphere";
$options["lock"] = "";
$options["stretchX"] = 1.0;
$options["stretchY"] = 1.0;
$options["decel"] = 0.92;
$options["physModel"] = true;
$options["maxInputZone"] = 0.25;
$options["minSpeed"] = 0.002;
$options["initialDecel"] = true;
module::set_var("tag_cloud_html5", "options_sidebar", json_encode($options));
$options = json_decode(module::get_var("tag_cloud_html5", "options_wholecloud"),true);
$options["deadZone"] = $options["deadZone"];
$options["shape"] = "sphere";
$options["lock"] = "";
$options["stretchX"] = 1.0;
$options["stretchY"] = 1.0;
$options["decel"] = 0.92;
$options["physModel"] = true;
$options["maxInputZone"] = 0.15;
$options["minSpeed"] = 0.002;
$options["initialDecel"] = true;
module::set_var("tag_cloud_html5", "options_wholecloud", json_encode($options));
}
// note: there are no variable changes for v6 and v7 upgrades
module::set_version("tag_cloud_html5", 7);
}
static function uninstall() {
module::clear_all_vars("tag_cloud_html5");
}
}

View File

@ -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-2013 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 tag_cloud_html5_theme_Core {
static function head($theme) {
$theme->script("jquery.tagcanvas.mod.min.js");
$theme->css("tag_cloud_html5.css");
}
}

View File

@ -0,0 +1,35 @@
// Copyright 2006 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
document.createElement("canvas").getContext||(function(){var s=Math,j=s.round,F=s.sin,G=s.cos,V=s.abs,W=s.sqrt,k=10,v=k/2;function X(){return this.context_||(this.context_=new H(this))}var L=Array.prototype.slice;function Y(b,a){var c=L.call(arguments,2);return function(){return b.apply(a,c.concat(L.call(arguments)))}}var M={init:function(b){if(/MSIE/.test(navigator.userAgent)&&!window.opera){var a=b||document;a.createElement("canvas");a.attachEvent("onreadystatechange",Y(this.init_,this,a))}},init_:function(b){b.namespaces.g_vml_||
b.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml","#default#VML");b.namespaces.g_o_||b.namespaces.add("g_o_","urn:schemas-microsoft-com:office:office","#default#VML");if(!b.styleSheets.ex_canvas_){var a=b.createStyleSheet();a.owningElement.id="ex_canvas_";a.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}g_vml_\\:*{behavior:url(#default#VML)}g_o_\\:*{behavior:url(#default#VML)}"}var c=b.getElementsByTagName("canvas"),d=0;for(;d<c.length;d++)this.initElement(c[d])},
initElement:function(b){if(!b.getContext){b.getContext=X;b.innerHTML="";b.attachEvent("onpropertychange",Z);b.attachEvent("onresize",$);var a=b.attributes;if(a.width&&a.width.specified)b.style.width=a.width.nodeValue+"px";else b.width=b.clientWidth;if(a.height&&a.height.specified)b.style.height=a.height.nodeValue+"px";else b.height=b.clientHeight}return b}};function Z(b){var a=b.srcElement;switch(b.propertyName){case "width":a.style.width=a.attributes.width.nodeValue+"px";a.getContext().clearRect();
break;case "height":a.style.height=a.attributes.height.nodeValue+"px";a.getContext().clearRect();break}}function $(b){var a=b.srcElement;if(a.firstChild){a.firstChild.style.width=a.clientWidth+"px";a.firstChild.style.height=a.clientHeight+"px"}}M.init();var N=[],B=0;for(;B<16;B++){var C=0;for(;C<16;C++)N[B*16+C]=B.toString(16)+C.toString(16)}function I(){return[[1,0,0],[0,1,0],[0,0,1]]}function y(b,a){var c=I(),d=0;for(;d<3;d++){var f=0;for(;f<3;f++){var h=0,g=0;for(;g<3;g++)h+=b[d][g]*a[g][f];c[d][f]=
h}}return c}function O(b,a){a.fillStyle=b.fillStyle;a.lineCap=b.lineCap;a.lineJoin=b.lineJoin;a.lineWidth=b.lineWidth;a.miterLimit=b.miterLimit;a.shadowBlur=b.shadowBlur;a.shadowColor=b.shadowColor;a.shadowOffsetX=b.shadowOffsetX;a.shadowOffsetY=b.shadowOffsetY;a.strokeStyle=b.strokeStyle;a.globalAlpha=b.globalAlpha;a.arcScaleX_=b.arcScaleX_;a.arcScaleY_=b.arcScaleY_;a.lineScale_=b.lineScale_}function P(b){var a,c=1;b=String(b);if(b.substring(0,3)=="rgb"){var d=b.indexOf("(",3),f=b.indexOf(")",d+
1),h=b.substring(d+1,f).split(",");a="#";var g=0;for(;g<3;g++)a+=N[Number(h[g])];if(h.length==4&&b.substr(3,1)=="a")c=h[3]}else a=b;return{color:a,alpha:c}}function aa(b){switch(b){case "butt":return"flat";case "round":return"round";case "square":default:return"square"}}function H(b){this.m_=I();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.fillStyle=this.strokeStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=k*1;this.globalAlpha=1;this.canvas=b;
var a=b.ownerDocument.createElement("div");a.style.width=b.clientWidth+"px";a.style.height=b.clientHeight+"px";a.style.overflow="hidden";a.style.position="absolute";b.appendChild(a);this.element_=a;this.lineScale_=this.arcScaleY_=this.arcScaleX_=1}var i=H.prototype;i.clearRect=function(){this.element_.innerHTML=""};i.beginPath=function(){this.currentPath_=[]};i.moveTo=function(b,a){var c=this.getCoords_(b,a);this.currentPath_.push({type:"moveTo",x:c.x,y:c.y});this.currentX_=c.x;this.currentY_=c.y};
i.lineTo=function(b,a){var c=this.getCoords_(b,a);this.currentPath_.push({type:"lineTo",x:c.x,y:c.y});this.currentX_=c.x;this.currentY_=c.y};i.bezierCurveTo=function(b,a,c,d,f,h){var g=this.getCoords_(f,h),l=this.getCoords_(b,a),e=this.getCoords_(c,d);Q(this,l,e,g)};function Q(b,a,c,d){b.currentPath_.push({type:"bezierCurveTo",cp1x:a.x,cp1y:a.y,cp2x:c.x,cp2y:c.y,x:d.x,y:d.y});b.currentX_=d.x;b.currentY_=d.y}i.quadraticCurveTo=function(b,a,c,d){var f=this.getCoords_(b,a),h=this.getCoords_(c,d),g={x:this.currentX_+
0.6666666666666666*(f.x-this.currentX_),y:this.currentY_+0.6666666666666666*(f.y-this.currentY_)};Q(this,g,{x:g.x+(h.x-this.currentX_)/3,y:g.y+(h.y-this.currentY_)/3},h)};i.arc=function(b,a,c,d,f,h){c*=k;var g=h?"at":"wa",l=b+G(d)*c-v,e=a+F(d)*c-v,m=b+G(f)*c-v,r=a+F(f)*c-v;if(l==m&&!h)l+=0.125;var n=this.getCoords_(b,a),o=this.getCoords_(l,e),q=this.getCoords_(m,r);this.currentPath_.push({type:g,x:n.x,y:n.y,radius:c,xStart:o.x,yStart:o.y,xEnd:q.x,yEnd:q.y})};i.rect=function(b,a,c,d){this.moveTo(b,
a);this.lineTo(b+c,a);this.lineTo(b+c,a+d);this.lineTo(b,a+d);this.closePath()};i.strokeRect=function(b,a,c,d){var f=this.currentPath_;this.beginPath();this.moveTo(b,a);this.lineTo(b+c,a);this.lineTo(b+c,a+d);this.lineTo(b,a+d);this.closePath();this.stroke();this.currentPath_=f};i.fillRect=function(b,a,c,d){var f=this.currentPath_;this.beginPath();this.moveTo(b,a);this.lineTo(b+c,a);this.lineTo(b+c,a+d);this.lineTo(b,a+d);this.closePath();this.fill();this.currentPath_=f};i.createLinearGradient=function(b,
a,c,d){var f=new D("gradient");f.x0_=b;f.y0_=a;f.x1_=c;f.y1_=d;return f};i.createRadialGradient=function(b,a,c,d,f,h){var g=new D("gradientradial");g.x0_=b;g.y0_=a;g.r0_=c;g.x1_=d;g.y1_=f;g.r1_=h;return g};i.drawImage=function(b){var a,c,d,f,h,g,l,e,m=b.runtimeStyle.width,r=b.runtimeStyle.height;b.runtimeStyle.width="auto";b.runtimeStyle.height="auto";var n=b.width,o=b.height;b.runtimeStyle.width=m;b.runtimeStyle.height=r;if(arguments.length==3){a=arguments[1];c=arguments[2];h=g=0;l=d=n;e=f=o}else if(arguments.length==
5){a=arguments[1];c=arguments[2];d=arguments[3];f=arguments[4];h=g=0;l=n;e=o}else if(arguments.length==9){h=arguments[1];g=arguments[2];l=arguments[3];e=arguments[4];a=arguments[5];c=arguments[6];d=arguments[7];f=arguments[8]}else throw Error("Invalid number of arguments");var q=this.getCoords_(a,c),t=[];t.push(" <g_vml_:group",' coordsize="',k*10,",",k*10,'"',' coordorigin="0,0"',' style="width:',10,"px;height:",10,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]){var E=[];E.push("M11=",
this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",j(q.x/k),",","Dy=",j(q.y/k),"");var p=q,z=this.getCoords_(a+d,c),w=this.getCoords_(a,c+f),x=this.getCoords_(a+d,c+f);p.x=s.max(p.x,z.x,w.x,x.x);p.y=s.max(p.y,z.y,w.y,x.y);t.push("padding:0 ",j(p.x/k),"px ",j(p.y/k),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",E.join(""),", sizingmethod='clip');")}else t.push("top:",j(q.y/k),"px;left:",j(q.x/k),"px;");t.push(' ">','<g_vml_:image src="',b.src,
'"',' style="width:',k*d,"px;"," height:",k*f,'px;"',' cropleft="',h/n,'"',' croptop="',g/o,'"',' cropright="',(n-h-l)/n,'"',' cropbottom="',(o-g-e)/o,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",t.join(""))};i.stroke=function(b){var a=[],c=P(b?this.fillStyle:this.strokeStyle),d=c.color,f=c.alpha*this.globalAlpha;a.push("<g_vml_:shape",' filled="',!!b,'"',' style="position:absolute;width:',10,"px;height:",10,'px;"',' coordorigin="0 0" coordsize="',k*10," ",k*10,'"',' stroked="',
!b,'"',' path="');var h={x:null,y:null},g={x:null,y:null},l=0;for(;l<this.currentPath_.length;l++){var e=this.currentPath_[l];switch(e.type){case "moveTo":a.push(" m ",j(e.x),",",j(e.y));break;case "lineTo":a.push(" l ",j(e.x),",",j(e.y));break;case "close":a.push(" x ");e=null;break;case "bezierCurveTo":a.push(" c ",j(e.cp1x),",",j(e.cp1y),",",j(e.cp2x),",",j(e.cp2y),",",j(e.x),",",j(e.y));break;case "at":case "wa":a.push(" ",e.type," ",j(e.x-this.arcScaleX_*e.radius),",",j(e.y-this.arcScaleY_*e.radius),
" ",j(e.x+this.arcScaleX_*e.radius),",",j(e.y+this.arcScaleY_*e.radius)," ",j(e.xStart),",",j(e.yStart)," ",j(e.xEnd),",",j(e.yEnd));break}if(e){if(h.x==null||e.x<h.x)h.x=e.x;if(g.x==null||e.x>g.x)g.x=e.x;if(h.y==null||e.y<h.y)h.y=e.y;if(g.y==null||e.y>g.y)g.y=e.y}}a.push(' ">');if(b)if(typeof this.fillStyle=="object"){var m=this.fillStyle,r=0,n={x:0,y:0},o=0,q=1;if(m.type_=="gradient"){var t=m.x1_/this.arcScaleX_,E=m.y1_/this.arcScaleY_,p=this.getCoords_(m.x0_/this.arcScaleX_,m.y0_/this.arcScaleY_),
z=this.getCoords_(t,E);r=Math.atan2(z.x-p.x,z.y-p.y)*180/Math.PI;if(r<0)r+=360;if(r<1.0E-6)r=0}else{var p=this.getCoords_(m.x0_,m.y0_),w=g.x-h.x,x=g.y-h.y;n={x:(p.x-h.x)/w,y:(p.y-h.y)/x};w/=this.arcScaleX_*k;x/=this.arcScaleY_*k;var R=s.max(w,x);o=2*m.r0_/R;q=2*m.r1_/R-o}var u=m.colors_;u.sort(function(ba,ca){return ba.offset-ca.offset});var J=u.length,da=u[0].color,ea=u[J-1].color,fa=u[0].alpha*this.globalAlpha,ga=u[J-1].alpha*this.globalAlpha,S=[],l=0;for(;l<J;l++){var T=u[l];S.push(T.offset*q+
o+" "+T.color)}a.push('<g_vml_:fill type="',m.type_,'"',' method="none" focus="100%"',' color="',da,'"',' color2="',ea,'"',' colors="',S.join(","),'"',' opacity="',ga,'"',' g_o_:opacity2="',fa,'"',' angle="',r,'"',' focusposition="',n.x,",",n.y,'" />')}else a.push('<g_vml_:fill color="',d,'" opacity="',f,'" />');else{var K=this.lineScale_*this.lineWidth;if(K<1)f*=K;a.push("<g_vml_:stroke",' opacity="',f,'"',' joinstyle="',this.lineJoin,'"',' miterlimit="',this.miterLimit,'"',' endcap="',aa(this.lineCap),
'"',' weight="',K,'px"',' color="',d,'" />')}a.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",a.join(""))};i.fill=function(){this.stroke(true)};i.closePath=function(){this.currentPath_.push({type:"close"})};i.getCoords_=function(b,a){var c=this.m_;return{x:k*(b*c[0][0]+a*c[1][0]+c[2][0])-v,y:k*(b*c[0][1]+a*c[1][1]+c[2][1])-v}};i.save=function(){var b={};O(this,b);this.aStack_.push(b);this.mStack_.push(this.m_);this.m_=y(I(),this.m_)};i.restore=function(){O(this.aStack_.pop(),
this);this.m_=this.mStack_.pop()};function ha(b){var a=0;for(;a<3;a++){var c=0;for(;c<2;c++)if(!isFinite(b[a][c])||isNaN(b[a][c]))return false}return true}function A(b,a,c){if(!!ha(a)){b.m_=a;if(c)b.lineScale_=W(V(a[0][0]*a[1][1]-a[0][1]*a[1][0]))}}i.translate=function(b,a){A(this,y([[1,0,0],[0,1,0],[b,a,1]],this.m_),false)};i.rotate=function(b){var a=G(b),c=F(b);A(this,y([[a,c,0],[-c,a,0],[0,0,1]],this.m_),false)};i.scale=function(b,a){this.arcScaleX_*=b;this.arcScaleY_*=a;A(this,y([[b,0,0],[0,a,
0],[0,0,1]],this.m_),true)};i.transform=function(b,a,c,d,f,h){A(this,y([[b,a,0],[c,d,0],[f,h,1]],this.m_),true)};i.setTransform=function(b,a,c,d,f,h){A(this,[[b,a,0],[c,d,0],[f,h,1]],true)};i.clip=function(){};i.arcTo=function(){};i.createPattern=function(){return new U};function D(b){this.type_=b;this.r1_=this.y1_=this.x1_=this.r0_=this.y0_=this.x0_=0;this.colors_=[]}D.prototype.addColorStop=function(b,a){a=P(a);this.colors_.push({offset:b,color:a.color,alpha:a.alpha})};function U(){}G_vmlCanvasManager=
M;CanvasRenderingContext2D=H;CanvasGradient=D;CanvasPattern=U})();

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,58 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 Form_Input extends Form_Input_Core {
/**
* Custom validation rule: numrange
* 0 args : returns error if not numeric
* 1 arg : returns error if not numeric OR if below min
* 2 args : returns error if not numeric OR if below min OR if above max
*/
protected function rule_numrange($min = null, $max = null) {
if (is_numeric($this->value)) {
if (!is_null($min) && ($this->value < $min)) {
// below min
$this->errors['numrange'] = true;
$this->error_messages['numrange'] = t('Value is below minimum of').' '.$min;
} elseif (!is_null($max) && ($this->value > $max)) {
// above max
$this->errors['numrange'] = true;
$this->error_messages['numrange'] = t('Value is above maximum of').' '.$max;;
}
} else {
// not numeric
$this->errors['numrange'] = true;
$this->error_messages['numrange'] = t('Value is not numeric');
}
}
/**
* Custom validation rule: color
* returns no error if string is formatted as #hhhhhh OR if string is empty
* to exclude the empty case, add "required" as another rule
*/
protected function rule_color() {
if (preg_match("/^#[0-9A-Fa-f]{6}$|^$/", $this->value) == 0) {
$this->errors['color'] = true;
$this->error_messages['color'] = t('Color is not in #hhhhhh format');
}
}
}

View File

@ -0,0 +1,7 @@
name = "Tag Cloud HTML5"
description = "HTML5-compliant tag cloud. Functions as non-Flash replacements for both 'tag_cloud' and 'tag_cloud_page' modules, with some extra features added."
version = 7
author_name = "Shad Laws"
author_url = ""
info_url = "http://codex.gallery2.org/Gallery3:Modules:tag_cloud_html5"
discuss_url = "http://gallery.menalto.com/node/106774"

View File

@ -0,0 +1,29 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<style>
@import "<?= url::file("modules/tag_cloud_html5/css/admin_tag_cloud_html5.css"); ?>";
</style>
<div id="g-tag-cloud-html5-admin">
<h2>
<?= t("Tag cloud HTML5 settings") ?>
</h2>
<p>
<b><?= t("Underlying JS libraries:") ?></b><br/>
<?= "1. <a href='http://www.goat1000.com/tagcanvas.php'>TagCanvas</a>: ".t("a non-flash, HTML5-compliant jQuery plugin.") ?><br/>
<?= "2. <a href='http://excanvas.sourceforge.net'>excanvas</a>: ".t("maintains canvas compatibility with pre-9.0 Internet Explorer, and does not load if not needed.") ?><br/>
<?= t("The module author, Shad Laws, has modified TagCanvas to add a physics-based model for motion and some extra parameters.") ?>
<?= t("Although this module loads a minified version of the JS library, the full-sized one is included in the JS directory for reference.") ?>
</p>
<p>
<b><?= t("How sizing works in TagCanvas:") ?></b><br/>
<?= "1. ".t("make a square the size of the minimum of width and height (as determined by width and height parameters)") ?><br/>
<?= "2. ".t("scale result by the stretch factors, possibility resulting in a non-square shape") ?><br/>
<?= "3. ".t("set text into result at defined text height") ?><br/>
<?= "4. ".t("scale result by the zoom, scaling both cloud and text height (e.g. text height 12 and zoom 1.25 results in 15pt font)") ?>
</p>
<p>
<b><?= t("Legend:") ?></b><br/>
<?= t("&nbsp;&nbsp;&nbsp;option name (more info on option) {related TagCanvas parameters}") ?><br/>
<?= t("More details on TagCanvas parameters given at TagCanvas's homepage or in the above-mentioned JS library.") ?>
</p>
<?= $form ?>
</div>

View File

@ -0,0 +1,40 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<!--[if lt IE 9]>
<?= html::script(gallery::find_file("js", "excanvas.compiled.js", false)) ?>
<![endif]-->
<script type="text/javascript">
$(document).ready(function() {
// set g-tag-cloud-html5-canvas size
$("#g-tag-cloud-html5-canvas").attr({
'width' : Math.floor($("#g-tag-cloud-html5").width()*<?= $width ?>),
'height': Math.floor($("#g-tag-cloud-html5").width()*<?= $height ?>)
});
// start g-tag-cloud-html5-canvas
if(!$('#g-tag-cloud-html5-canvas').tagcanvas(<?= $options ?>,'g-tag-cloud-html5-tags')) {
// something went wrong, hide the canvas container g-tag-cloud-html5
$('#g-tag-cloud-html5').hide();
};
// tag autocomplete for g-add-tag-form
$("#g-add-tag-form input:text").autocomplete(
"<?= url::site("/tags/autocomplete") ?>", {
max: 30,
multiple: true,
multipleSeparator: ',',
cacheLength: 1}
);
});
</script>
<div id="g-tag-cloud-html5">
<canvas id="g-tag-cloud-html5-canvas">
<? echo t('Tag cloud loading...'); ?>
</canvas>
</div>
<div id="g-tag-cloud-html5-tags">
<?= $cloud ?>
</div>
<?= $wholecloud_link ?>
<?= $form ?>

View File

@ -0,0 +1,59 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<!--[if lt IE 9]>
<?= html::script(gallery::find_file("js", "excanvas.compiled.js", false)) ?>
<![endif]-->
<script type="text/javascript">
// define flag variables if not already defined elsewhere
if (typeof(jQueryScriptFlag) == 'undefined') {
var jQueryScriptFlag = false;
};
if (typeof(jQueryTagCanvasScriptFlag) == 'undefined') {
var jQueryTagCanvasScriptFlag = false;
};
function initScripts() {
// load scripts if not already loaded
if (typeof(jQuery) == 'undefined') {
if (!jQueryScriptFlag) {
// load both scripts
jQueryScriptFlag = true;
jQueryTagCanvasScriptFlag = true;
document.write("<scr" + "ipt type=\"text/javascript\" src=\"<?= url::base(false).gallery::find_file("js", "jquery.js", false) ?>\"></scr" + "ipt>");
document.write("<scr" + "ipt type=\"text/javascript\" src=\"<?= url::base(false).gallery::find_file("js", "jquery.tagcanvas.mod.min.js", false) ?>\"></scr" + "ipt>");
};
setTimeout("initScripts()", 50);
} else if (typeof(jQuery().tagcanvas) == 'undefined') {
if (!jQueryTagCanvasScriptFlag) {
// load one script
jQueryTagCanvasScriptFlag = true;
document.write("<scr" + "ipt type=\"text/javascript\" src=\"<?= url::base(false).gallery::find_file("js", "jquery.tagcanvas.mod.min.js", false) ?>\"></scr" + "ipt>");
};
setTimeout("initScripts()", 50);
} else {
// libraries loaded - run actual code
function redraw() {
// set g-tag-cloud-html5-embed-canvas size
$("#g-tag-cloud-html5-embed-canvas").attr({
'width' : $("#g-tag-cloud-html5-embed").parent().width(),
'height': $("#g-tag-cloud-html5-embed").parent().height()
});
// start g-tag-cloud-html5-embed-canvas
if(!$('#g-tag-cloud-html5-embed-canvas').tagcanvas(<?= $options ?>,'g-tag-cloud-html5-embed-tags')) {
// something went wrong, hide the canvas container g-tag-cloud-html5-embed
$('#g-tag-cloud-html5-embed').hide();
};
};
// resize and redraw the canvas
$(document).ready(redraw);
$(window).resize(redraw);
};
};
initScripts();
</script>
<div id="g-tag-cloud-html5-embed">
<canvas id="g-tag-cloud-html5-embed-canvas">
<? echo t('Tag cloud loading...'); ?>
</canvas>
</div>
<div id="g-tag-cloud-html5-embed-tags" style="display: none">
<?= $cloud ?>
</div>

View File

@ -0,0 +1,40 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<!--[if lt IE 9]>
<?= html::script(gallery::find_file("js", "excanvas.compiled.js", false)) ?>
<![endif]-->
<script type="text/javascript">
function redraw() {
// set g-tag-cloud-html5-page-canvas size
$("#g-tag-cloud-html5-page-canvas").attr({
'width' : Math.floor(Math.min( $(window).height()*<?= $width ?>, $("#g-tag-cloud-html5-page").width() )),
'height': Math.floor( $(window).height()*<?= $height ?> )
});
// start g-tag-cloud-html5-page-canvas
if(!$('#g-tag-cloud-html5-page-canvas').tagcanvas(<?= $options ?>,'g-tag-cloud-html5-page-tags')) {
// something went wrong, hide the canvas container g-tag-cloud-html5-page
$('#g-tag-cloud-html5-page').hide();
};
};
// resize and redraw the canvas
$(window).resize(redraw);
$(document).ready(redraw);
</script>
<div id="g-tag-cloud-html5-page-header">
<div id="g-tag-cloud-html5-page-buttons">
<?= $theme->dynamic_top() ?>
</div>
<h1><?= html::clean($title) ?></h1>
</div>
<div id="g-tag-cloud-html5-page">
<canvas id="g-tag-cloud-html5-page-canvas">
<? echo t('Tag cloud loading...'); ?>
</canvas>
</div>
<div id="g-tag-cloud-html5-page-tags">
<?= $cloud ?>
</div>
<?= $theme->dynamic_bottom() ?>

View File

@ -0,0 +1,53 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 user_albums_event_Core {
/**
* Create an album for the newly created user and give him view and edit permissions.
*/
static function user_created($user) {
// Create a group with the same name, if necessary
$group_name = "auto: {$user->name}";
$group = identity::lookup_group_by_name($group_name);
if (!$group) {
$group = identity::create_group($group_name);
identity::add_user_to_group($user, $group);
}
// Create an album for the user, if it doesn't exist
$album = ORM::factory("item")
->where("parent_id", "=", item::root()->id)
->where("name", "=", $user->name)
->find();
if (!$album->loaded()) {
$album->type = "album";
$album->name = $user->name;
$album->title = "{$user->name}'s album";
$album->parent_id = item::root()->id;
$album->sort_column = "weight";
$album->sort_order = "asc";
$album->save();
access::allow($group, "view", item::root());
access::allow($group, "view_full", $album);
access::allow($group, "edit", $album);
access::allow($group, "add", $album);
}
}
}

View File

@ -0,0 +1,7 @@
name = "User Albums"
description = "Create a personal album for new users"
version = 1
author_name = ""
author_url = ""
info_url = "http://codex.gallery2.org/Gallery3:Modules:user_albums"
discuss_url = "http://gallery.menalto.com/forum_module_user_albums"

View File

@ -0,0 +1,38 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 albumtree_block_Core {
static function get_site_list() {
return array("albumtree" => t("Album tree"));
}
static function get($block_id) {
$block = new Block();
switch ($block_id) {
case "albumtree":
$style = module::get_var("albumtree", "style", "select");
$block->css_id = "g-albumtree";
$block->title = t("Album Tree");
$block->content = new View("albumtree_block_{$style}.html");
$block->content->root = item::root();
break;
}
return $block;
}
}

View File

@ -0,0 +1,33 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 albumtree_installer {
static function install() {
module::set_var("albumtree", "style", "select");
module::set_version("albumtree", 3);
}
static function upgrade($version) {
$db = Database::instance();
if ($version == 1) {
module::set_var("albumtree", "style", "select");
module::set_version("albumtree", $version = 2);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 B

BIN
modules/albumtree/images/join.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
modules/albumtree/images/line.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
modules/albumtree/images/plus.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

7
modules/albumtree/module.info Executable file
View File

@ -0,0 +1,7 @@
name = "Album Tree"
description = "Provides a block in the sidebar with quick links to all other albums."
version = 3
author_name = ""
author_url = ""
info_url = "http://codex.gallery2.org/Gallery3:Modules:albumtree"
discuss_url = "http://gallery.menalto.com/forum_module_albumtree"

View File

@ -0,0 +1,413 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<script type="text/javascript">
/*--------------------------------------------------|
| dTree 2.05 | www.destroydrop.com/javascript/tree/ |
|---------------------------------------------------|
| Copyright (c) 2002-2003 Geir Landrö |
| |
| This script can be used freely as long as all |
| copyright messages are intact. |
| |
| Updated: 17.04.2003 |
|--------------------------------------------------*/
// Node object
function Node(id, pid, name, url, title, target, icon, iconOpen, open) {
this.id = id;
this.pid = pid;
this.name = name;
this.url = url;
this.title = title;
this.target = target;
this.icon = icon;
this.iconOpen = iconOpen;
this._io = open || false;
this._is = false;
this._ls = false;
this._hc = false;
this._ai = 0;
this._p;
};
// Tree object
function dTree(objName) {
this.config = {
target : null,
folderLinks : true,
useSelection : true,
useCookies : true,
useLines : true,
useIcons : false,
useStatusText : false,
closeSameLevel : false,
inOrder : false,
cookiePath : null,
cookieDomain : null
}
this.obj = objName;
this.aNodes = [];
this.aIndent = [];
this.root = new Node(-1);
this.selectedNode = null;
this.selectedFound = false;
this.completed = false;
};
// Adds a new node to the node array
dTree.prototype.add = function(id, pid, name, url, title, target, icon, iconOpen, open) {
this.aNodes[this.aNodes.length] = new Node(id, pid, name, url, title, target, icon, iconOpen, open);
};
// Open/close all nodes
dTree.prototype.openAll = function() {
this.oAll(true);
};
dTree.prototype.closeAll = function() {
this.oAll(false);
};
// Outputs the tree to the page
dTree.prototype.toString = function() {
var str = '<div class="dtree">\n';
if (document.getElementById) {
if (this.config.useCookies) this.selectedNode = this.getSelected();
str += this.addNode(this.root);
} else str += 'Browser not supported.';
str += '</div>';
if (!this.selectedFound) this.selectedNode = null;
this.completed = true;
return str;
};
// Creates the tree structure
dTree.prototype.addNode = function(pNode) {
var str = '';
var n=0;
if (this.config.inOrder) n = pNode._ai;
for (n; n<this.aNodes.length; n++) {
if (this.aNodes[n].pid == pNode.id) {
var cn = this.aNodes[n];
cn._p = pNode;
cn._ai = n;
this.setCS(cn);
if (!cn.target && this.config.target) cn.target = this.config.target;
if (cn._hc && !cn._io && this.config.useCookies) cn._io = this.isOpen(cn.id);
if (!this.config.folderLinks && cn._hc) cn.url = null;
if (this.config.useSelection && cn.id == this.selectedNode && !this.selectedFound) {
cn._is = true;
this.selectedNode = n;
this.selectedFound = true;
}
str += this.node(cn, n);
if (cn._ls) break;
}
}
return str;
};
// Creates the node icon, url and text
dTree.prototype.node = function(node, nodeId) {
var str = '<div class="dTreeNode" title="' + node.name + '">' + this.indent(node, nodeId);
if (this.config.useIcons) {
if (!node.icon) node.icon = (this.root.id == node.pid) ? this.icon.root : ((node._hc) ? this.icon.folder : this.icon.node);
if (!node.iconOpen) node.iconOpen = (node._hc) ? this.icon.folderOpen : this.icon.node;
if (this.root.id == node.pid) {
node.icon = this.icon.root;
node.iconOpen = this.icon.root;
}
str += '<img id="i' + this.obj + nodeId + '" src="' + ((node._io) ? node.iconOpen : node.icon) + '" alt="" />';
}
if (node.url) {
str += '<a id="s' + this.obj + nodeId + '" class="' + ((this.config.useSelection) ? ((node._is ? 'nodeSel' : 'node')) : 'node') + '" href="' + node.url + '"';
if (node.title) str += ' title="' + node.title + '"';
if (node.target) str += ' target="' + node.target + '"';
if (this.config.useStatusText) str += ' onmouseover="window.status=\'' + node.name + '\';return true;" onmouseout="window.status=\'\';return true;" ';
if (this.config.useSelection && ((node._hc && this.config.folderLinks) || !node._hc))
str += ' onclick="' + this.obj + '.s(' + nodeId + ');"';
str += '>';
}
else if ((!this.config.folderLinks || !node.url) && node._hc && node.pid != this.root.id)
str += '<a href="javascript: ' + this.obj + '.o(' + nodeId + ');" class="node">';
str += node.name;
if (node.url || ((!this.config.folderLinks || !node.url) && node._hc)) str += '</a>';
str += '</div>';
if (node._hc) {
str += '<div id="d' + this.obj + nodeId + '" class="clip" style="display:' + ((this.root.id == node.pid || node._io) ? 'block' : 'none') + ';">';
str += this.addNode(node);
str += '</div>';
}
this.aIndent.pop();
return str;
};
// Adds the empty and line icons
dTree.prototype.indent = function(node, nodeId) {
var str = '';
if (this.root.id != node.pid) {
for (var n=0; n<this.aIndent.length; n++)
str += '<img src="' + ( (this.aIndent[n] == 1 && this.config.useLines) ? this.icon.line : this.icon.empty ) + '" alt="" />';
(node._ls) ? this.aIndent.push(0) : this.aIndent.push(1);
if (node._hc) {
str += '<a href="javascript: ' + this.obj + '.o(' + nodeId + ');"><img id="j' + this.obj + nodeId + '" src="';
if (!this.config.useLines) str += (node._io) ? this.icon.nlMinus : this.icon.nlPlus;
else str += ( (node._io) ? ((node._ls && this.config.useLines) ? this.icon.minusBottom : this.icon.minus) : ((node._ls && this.config.useLines) ? this.icon.plusBottom : this.icon.plus ) );
str += '" alt="" /></a>';
} else str += '<img src="' + ( (this.config.useLines) ? ((node._ls) ? this.icon.joinBottom : this.icon.join ) : this.icon.empty) + '" alt="" />';
}
return str;
};
// Checks if a node has any children and if it is the last sibling
dTree.prototype.setCS = function(node) {
var lastId;
for (var n=0; n<this.aNodes.length; n++) {
if (this.aNodes[n].pid == node.id) node._hc = true;
if (this.aNodes[n].pid == node.pid) lastId = this.aNodes[n].id;
}
if (lastId==node.id) node._ls = true;
};
// Returns the selected node
dTree.prototype.getSelected = function() {
var sn = this.getCookie('cs' + this.obj);
return (sn) ? sn : null;
};
// Highlights the selected node
dTree.prototype.s = function(id) {
if (!this.config.useSelection) return;
var cn = this.aNodes[id];
if (cn._hc && !this.config.folderLinks) return;
if (this.selectedNode != id) {
if (this.selectedNode || this.selectedNode==0) {
eOld = document.getElementById("s" + this.obj + this.selectedNode);
eOld.className = "node";
}
eNew = document.getElementById("s" + this.obj + id);
eNew.className = "nodeSel";
this.selectedNode = id;
if (this.config.useCookies) this.setCookie('cs' + this.obj, cn.id);
}
};
// Toggle Open or close
dTree.prototype.o = function(id) {
var cn = this.aNodes[id];
this.nodeStatus(!cn._io, id, cn._ls);
cn._io = !cn._io;
if (this.config.closeSameLevel) this.closeLevel(cn);
if (this.config.useCookies) this.updateCookie();
};
// Open or close all nodes
dTree.prototype.oAll = function(status) {
for (var n=0; n<this.aNodes.length; n++) {
if (this.aNodes[n]._hc && this.aNodes[n].pid != this.root.id) {
this.nodeStatus(status, n, this.aNodes[n]._ls)
this.aNodes[n]._io = status;
}
}
if (this.config.useCookies) this.updateCookie();
};
// Opens the tree to a specific node
dTree.prototype.openTo = function(nId, bSelect, bFirst) {
if (!bFirst) {
for (var n=0; n<this.aNodes.length; n++) {
if (this.aNodes[n].id == nId) {
nId=n;
break;
}
}
}
var cn=this.aNodes[nId];
if (cn.pid==this.root.id || !cn._p) return;
cn._io = true;
cn._is = bSelect;
if (this.completed && cn._hc) this.nodeStatus(true, cn._ai, cn._ls);
if (this.completed && bSelect) this.s(cn._ai);
else if (bSelect) this._sn=cn._ai;
this.openTo(cn._p._ai, false, true);
};
// Closes all nodes on the same level as certain node
dTree.prototype.closeLevel = function(node) {
for (var n=0; n<this.aNodes.length; n++) {
if (this.aNodes[n].pid == node.pid && this.aNodes[n].id != node.id && this.aNodes[n]._hc) {
this.nodeStatus(false, n, this.aNodes[n]._ls);
this.aNodes[n]._io = false;
this.closeAllChildren(this.aNodes[n]);
}
}
}
// Closes all children of a node
dTree.prototype.closeAllChildren = function(node) {
for (var n=0; n<this.aNodes.length; n++) {
if (this.aNodes[n].pid == node.id && this.aNodes[n]._hc) {
if (this.aNodes[n]._io) this.nodeStatus(false, n, this.aNodes[n]._ls);
this.aNodes[n]._io = false;
this.closeAllChildren(this.aNodes[n]);
}
}
}
// Change the status of a node(open or closed)
dTree.prototype.nodeStatus = function(status, id, bottom) {
eDiv = document.getElementById('d' + this.obj + id);
eJoin = document.getElementById('j' + this.obj + id);
if (this.config.useIcons) {
eIcon = document.getElementById('i' + this.obj + id);
eIcon.src = (status) ? this.aNodes[id].iconOpen : this.aNodes[id].icon;
}
eJoin.src = (this.config.useLines)?
((status)?((bottom)?this.icon.minusBottom:this.icon.minus):((bottom)?this.icon.plusBottom:this.icon.plus)):
((status)?this.icon.nlMinus:this.icon.nlPlus);
eDiv.style.display = (status) ? 'block': 'none';
};
// [Cookie] Clears a cookie
dTree.prototype.clearCookie = function() {
var now = new Date();
var yesterday = new Date(now.getTime() - 1000 * 60 * 60 * 24);
this.setCookie('co'+this.obj, 'cookieValue', yesterday);
this.setCookie('cs'+this.obj, 'cookieValue', yesterday);
};
// [Cookie] Sets value in a cookie
dTree.prototype.setCookie = function(cookieName, cookieValue, expires, path, domain, secure) {
path = path || this.config.cookiePath;
domain = domain || this.config.cookieDomain;
document.cookie =
escape(cookieName) + '=' + escape(cookieValue)
+ (expires ? '; expires=' + expires.toGMTString() : '')
+ (path ? '; path=' + path : '')
+ (domain ? '; domain=' + domain : '')
+ (secure ? '; secure' : '');
};
// [Cookie] Gets a value from a cookie
dTree.prototype.getCookie = function(cookieName) {
var cookieValue = '';
var posName = document.cookie.indexOf(escape(cookieName) + '=');
if (posName != -1) {
var posValue = posName + (escape(cookieName) + '=').length;
var endPos = document.cookie.indexOf(';', posValue);
if (endPos != -1) cookieValue = unescape(document.cookie.substring(posValue, endPos));
else cookieValue = unescape(document.cookie.substring(posValue));
}
return (cookieValue);
};
// [Cookie] Returns ids of open nodes as a string
dTree.prototype.updateCookie = function() {
var str = '';
for (var n=0; n<this.aNodes.length; n++) {
if (this.aNodes[n]._io && this.aNodes[n].pid != this.root.id) {
if (str) str += '.';
str += this.aNodes[n].id;
}
}
this.setCookie('co' + this.obj, str);
};
// [Cookie] Checks if a node id is in a cookie
dTree.prototype.isOpen = function(id) {
var aOpen = this.getCookie('co' + this.obj).split('.');
for (var n=0; n<aOpen.length; n++)
if (aOpen[n] == id) return true;
return false;
};
// If Push and pop is not implemented by the browser
if (!Array.prototype.push) {
Array.prototype.push = function array_push() {
for(var i=0;i<arguments.length;i++)
this[this.length]=arguments[i];
return this.length;
}
};
if (!Array.prototype.pop) {
Array.prototype.pop = function array_pop() {
lastElement = this[this.length-1];
this.length = Math.max(this.length-1,0);
return lastElement;
}
};
</script>
<style type="text/css">
/*--------------------------------------------------|
| dTree 2.05 | www.destroydrop.com/javascript/tree/ |
|---------------------------------------------------|
| Copyright (c) 2002-2003 Geir Landrö |
|--------------------------------------------------*/
.dtree {
white-space: nowrap;
}
.dtree img {
border: 0px;
vertical-align: middle;
}
.dtree a.node, .dtree a.nodeSel {
white-space: nowrap;
padding: 1px 2px 1px 2px;
}
.dtree a.nodeSel {
font-style: italic;
}
.dtree .clip {
overflow: hidden;
}
</style>
<div class="block-albumselect-AlbumTree gbBlock">
<div class="dtree">
<script type="text/javascript">
// <![CDATA[
function albumSelect_goToNode(nodeId) {
document.location = new String('main.php?g2_itemId=__ID__').replace('__ID__', nodeId);
}
var albumTree = new dTree('albumTree');
var albumTree_images = 'https://gallery315.dajavous.com/modules/albumtree/images/'
albumTree.icon = {
root : albumTree_images + 'base.gif',
folder : albumTree_images + 'folder.gif',
folderOpen : albumTree_images + 'imgfolder.gif',
node : albumTree_images + 'imgfolder.gif',
empty : albumTree_images + 'empty.gif',
line : albumTree_images + 'line.gif',
join : albumTree_images + 'join.gif',
joinBottom : albumTree_images + 'joinbottom.gif',
plus : albumTree_images + 'plus.gif',
plusBottom : albumTree_images + 'plusbottom.gif',
minus : albumTree_images + 'minus.gif',
minusBottom : albumTree_images + 'minusbottom.gif',
nlPlus : albumTree_images + 'nolines_plus.gif',
nlMinus : albumTree_images + 'nolines_minus.gif'
};
albumTree.config.useLines = true;
albumTree.config.useIcons = false;
albumTree.config.useCookies = false;
albumTree.config.closeSameLevel = false;
albumTree.config.cookiePath = '<?= item::root()->url() ?>';
albumTree.config.cookieDomain = '';
{ var pf = '<?= item::root()->url() ?>';
<?
function addtree($album){
?>
albumTree.add(<?= $album->id -1 ?>, <?= $album->parent_id -1 ?>, "<?= html::purify($album->title) ?>", pf+'<?= $album->relative_url() ?>');
<?
foreach ($album->viewable()->children(null, null, array(array("tag_album", "=", "album"))) as $child){
addtree($child);
}
}
addtree($root);
?>
}
document.write(albumTree);
// ]]>
</script>
</div>
</div>

View File

@ -0,0 +1,30 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<style type="text/css">
ul.treealbumnav {
height: 225px;
width: 190px;
overflow: auto;
border: 1px solid #666;
padding: 2px;
}
</style>
<ul class="treealbumnav">
<?
function makelist($album,$level){
//print out the list item
?>
<li>
<a href="<?= item::root()->url() ?><?= $album->relative_url() ?>"><?= str_repeat("&nbsp;&nbsp;", $level) ?><?= html::purify($album->title) ?></a>
</li>
<?
//recurse over the children, and print their list items as well
foreach ($album->viewable()->children(null, null, array(array("type", "=", "album"))) as $child){
makelist($child,$level+1);
}
}
makelist($root,0);
?>
</ul>

View File

@ -0,0 +1,16 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<select onchange="window.location=this.value">
<?
function makeselect($album, $level){
//print out the list item as a select option
?>
<option value="<?= item::root()->url() ?><?= $album->relative_url() ?>"><?= str_repeat("&nbsp;&nbsp;", $level) ?><?= html::purify($album->title) ?></option>
<?
//recurse over the children, and print their list items as well
foreach ($album->viewable()->children(null, null, array(array("type", "=", "album"))) as $child){
makeselect($child,$level+1);
}
}
makeselect($root,0);
?>
</select>

View File

@ -0,0 +1,24 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 arrow_nav_theme {
static function head($theme) {
return $theme->script("arrow_nav.js");
}
}

View File

@ -0,0 +1,74 @@
(function ($) {
'use strict';
var slideshowOpen = false,
direction = 'ltr',
keyPrevious = 37,
keyNext = 39,
keyDelete = 119,
url;
$(document).ready(function() {
direction = $(document.body).css("direction");
if (direction === 'rtl') {
keyPrevious = 39;
keyNext = 37;
}
if (typeof cooliris !== 'undefined') {
if ('embed' in cooliris) {
var show = cooliris.embed.show;
cooliris.embed.show = function() {
slideshowOpen = true;
show.apply(this, arguments);
};
}
}
});
$(document).keydown(function(e) {
// do not interfere with browser defaults like history navigation etc.
if (e.altKey || e.shiftKey || e.ctrlKey || e.metaKey) { return; }
// do nothing if event happens inside form elements
if (e.target.form && e.target.form.nodeType && e.target.form.nodeType === 1) { return; }
// do not interfere with slideshow control
if (slideshowOpen) {
// check if it's still there
slideshowOpen = false;
$(document).find('object').each(function(){
if (/cooliris/.test(this.data)) {
slideshowOpen = true;
return;
}
});
if (slideshowOpen) { return; }
}
switch (e.keyCode) {
case keyPrevious:
url = $('.g-paginator .g-first a').eq(0).attr("href");
break;
case keyNext:
url = $('.g-paginator .g-text-right a').eq(0).attr("href");
break;
case keyDelete:
$('a.g-dialog-link.g-quick-delete').click();
return false;
}
if (url !== undefined) {
window.location = url;
return false;
}
});
})(jQuery);

7
modules/arrow_nav/module.info Executable file
View File

@ -0,0 +1,7 @@
name = "Arrow Navigation"
description = "Use the left/right arrow keys to go to the previous/next page"
version = 4
author_name = ""
author_url = ""
info_url = "http://codex.galleryproject.org/Gallery3:Modules:arrow_nav"
discuss_url = ""

View File

@ -0,0 +1,117 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2021 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 BatchTag_Controller extends Controller {
public function tagitems() {
// Tag all non-album items in the current album with the specified tags.
// Prevent Cross Site Request Forgery
access::verify_csrf();
$input = Input::instance();
url::redirect(url::abs_site("batchtag/tagitems2?name={$input->post('name')}&item_id={$input->post('item_id')}&tag_subitems={$input->post('tag_subitems')}&csrf={$input->post('csrf')}"));
}
public function tagitems2() {
// Tag all non-album items in the current album with the specified tags.
// Prevent Cross Site Request Forgery
access::verify_csrf();
$input = Input::instance();
// Variables
if (($input->get("batchtag_max") == false) || ($input->get("batchtag_max") == "0")) {
$batchtag_max = "50";
} else {
$batchtag_max = $input->get("batchtag_max");
}
if ($input->get("batchtag_items_processed") == false) {
$batchtag_items_processed = "0";
} else {
$batchtag_items_processed = $input->get("batchtag_items_processed");
}
// Figure out if the contents of sub-albums should also be tagged
$str_tag_subitems = $input->get("tag_subitems");
$children = "";
if ($str_tag_subitems == false) {
// Generate an array of all non-album items in the current album.
$children = ORM::factory("item")
->where("parent_id", "=", $input->get("item_id"))
->where("type", "!=", "album")
->find_all();
} else {
// Generate an array of all non-album items in the current album
// and any sub albums.
$item = ORM::factory("item", $input->get("item_id"));
$children = $item->descendants();
}
// Loop through each item in the album and make sure the user has
// access to view and edit it.
$children_count = "0";
$tag_count = "0";
//echo Kohana::debug($children);
echo '<style>.continue { margin: 5em auto; text-align: center; }</style>';
foreach ($children as $child) {
if ($tag_count < $batchtag_max) {
if ($children_count >= $batchtag_items_processed) {
if (access::can("view", $child) && access::can("edit", $child) && !$child->is_album()) {
// Assuming the user can view/edit the current item, loop
// through each tag that was submitted and apply it to
// the current item.
foreach (explode(",", $input->get("name")) as $tag_name) {
$tag_name = trim($tag_name);
if ($tag_name) {
tag::add($child, $tag_name);
}
// $tag_count should be inside the foreach loop as it is depending on the number of time tag:add is run
$tag_count++;
}
}
echo '<style>.c' . $children_count . ' { display:none; }</style>' . "\n";
$children_count++;
$batchtag_max_new = $tag_count;
echo '<div class="continue c' . $children_count . '"><a href="' . url::abs_site("batchtag/tagitems2?name={$input->get('name')}&item_id={$input->get('item_id')}&tag_subitems={$input->get('tag_subitems')}&batchtag_items_processed=$children_count&batchtag_max=$batchtag_max_new&csrf={$input->get('csrf')}") . '">Continue</a></div>';
} else { $children_count++; }
} else { break; }
}
if ($tag_count < $batchtag_max) {
// Redirect back to the album.
$item = ORM::factory("item", $input->get("item_id"));
url::redirect(url::abs_site("{$item->type}s/{$item->id}"));
//echo url::abs_site("{$item->type}s/{$item->id}");
} else {
url::redirect(url::abs_site("batchtag/tagitems2?name={$input->get('name')}&item_id={$input->get('item_id')}&tag_subitems={$input->get('tag_subitems')}&batchtag_items_processed=$children_count&batchtag_max=$batchtag_max&csrf={$input->get('csrf')}"));
//echo url::abs_site("batchtag/tagitems2?name={$input->get('name')}&item_id={$input->get('item_id')}&tag_subitems={$input->get('tag_subitems')}&batchtag_items_processed=$children_count&batchtag_max=$batchtag_max&csrf={$input->get('csrf')}");
}
}
}

View File

@ -0,0 +1,61 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2021 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 batchtag_block_Core {
static function get_site_list() {
return array("batch_tag" => t("Batch Tag"));
}
static function get($block_id, $theme) {
$block = "";
// Only display on album pages that the user can edit.
$item = $theme->item();
if (!$item || !$item->is_album() || !access::can("edit", $item)) {
return;
}
switch ($block_id) {
case "batch_tag":
// Make a new sidebar block.
$block = new Block();
$block->css_id = "g-batch-tag";
$block->title = t("Batch Tag");
$block->content = new View("batchtag_block.html");
// Make a new form to place in the sidebar block.
$form = new Forge("batchtag/tagitems", "", "post",
array("id" => "g-batch-tag-form"));
$label = t("Tag everything in this album:");
$group = $form->group("add_tag")->label("Add Tag");
$group->input("name")->label($label)->rules("required|length[1,64]");
$group->checkbox("tag_subitems")
->label(t("Include sub-albums?"))
->value(true)
->checked(false);
$group->hidden("item_id")->value($item->id);
$group->submit("")->value(t("Add Tag"));
$block->content->batch_tag_form = $form;
break;
}
return $block;
}
}

View File

@ -0,0 +1,40 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2021 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 batchtag_event_Core {
static function pre_deactivate($data) {
if ($data->module == "tag") {
$data->messages["warn"][] = t("The BatchTag module requires the Tags module.");
}
}
static function module_change($changes) {
// See if the Tags module is installed,
// tell the user to install it if it isn't.
if (!module::is_active("tag") || in_array("tag", $changes->deactivate)) {
site_status::warning(
t("The BatchTag module requires the Tags module. " .
"<a href=\"%url\">Activate the Tags module now</a>",
array("url" => url::site("admin/modules"))),
"batchtag_needs_tag");
} else {
site_status::clear("batchtag_needs_tag");
}
}
}

View File

@ -0,0 +1,41 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2021 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 batchtag_installer {
static function install() {
// Set the module's version number.
module::set_version("batchtag", 1);
}
static function deactivate() {
site_status::clear("batchtag_needs_tag");
}
static function can_activate() {
$messages = array();
if (!module::is_active("tag")) {
$messages["warn"][] = t("The BatchTag module requires the Tags module.");
}
return $messages;
}
static function uninstall() {
module::delete("batchtag");
}
}

7
modules/batchtag/module.info Executable file
View File

@ -0,0 +1,7 @@
name = "BatchTag"
description = "Automatically apply a tag to the entire contents of an album."
version = 1
author_name = "rWatcher"
author_url = "http://codex.gallery2.org/User:RWatcher"
info_url = "https://gallery3-contrib.gitlab.io/#Documentation:27018350"
discuss_url = "https://gitlab.com/eric2001/batchtag/-/issues"

View File

@ -0,0 +1,8 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<script type="text/javascript">
$("#g-batch-tag-form").ready(function() {
var url = '<?= url::site("tags/autocomplete") ?>';
$("#g-batch-tag-form input:text").gallery_autocomplete(url, {multiple: true});
});
</script>
<?= $batch_tag_form ?>

View File

@ -0,0 +1,84 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 Captionator_Controller extends Controller {
function dialog($album_id) {
$album = ORM::factory("item", $album_id);
access::required("view", $album);
if (!access::can("edit", $album)) {
// The user can't edit; perhaps they just logged out?
url::redirect($album->abs_url());
}
$v = new Theme_View("page.html", "collection", "captionator");
$v->content = new View("captionator_dialog.html");
$v->content->album = $album;
$v->content->enable_tags = module::is_active("tag");
if ($v->content->enable_tags) {
$v->content->tags = array();
foreach ($album->viewable()->children() as $child) {
$item = ORM::factory("item", $child->id);
$tag_names = array();
foreach (tag::item_tags($item) as $tag) {
$tag_names[] = $tag->name;
}
$v->content->tags[$child->id] = implode(", ", $tag_names);
}
}
print $v;
}
function save($album_id) {
access::verify_csrf();
$album = ORM::factory("item", $album_id);
access::required("edit", $album);
if (Input::instance()->post("save")) {
$titles = Input::instance()->post("title");
$descriptions = Input::instance()->post("description");
$filenames = Input::instance()->post("filename");
$internetaddresses = Input::instance()->post("internetaddress");
$tags = Input::instance()->post("tags");
$enable_tags = module::is_active("tag");
foreach (array_keys($titles) as $id) {
$item = ORM::factory("item", $id);
if ($item->loaded() && access::can("edit", $item)) {
$item->title = $titles[$id];
$item->description = $descriptions[$id];
$item->name = $filenames[$id];
$item->slug = $internetaddresses[$id];
$item->save();
if ($enable_tags) {
tag::clear_all($item);
foreach (explode(",", $tags[$id]) as $tag_name) {
if ($tag_name) {
tag::add($item, trim($tag_name));
}
}
tag::compact();
}
}
}
message::success(t("Captions saved"));
}
url::redirect($album->abs_url());
}
}

View File

@ -0,0 +1,33 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 captionator_event_Core {
static function site_menu($menu, $theme) {
$item = $theme->item();
if ($item && $item->is_album() && access::can("edit", $item)) {
$menu->get("options_menu")
->append(Menu::factory("link")
->id("captionator")
->label(t("Caption album"))
->css_id("g-menu-captionator-link")
->url(url::site("captionator/dialog/{$item->id}")));
}
}
}

View File

@ -0,0 +1,7 @@
name = "Captionator"
description = "Caption all photos, movies and albums in an album at once."
version = 1
author_name = ""
author_url = ""
info_url = "http://codex.gallery2.org/Gallery3:Modules:captionator"
discuss_url = "http://gallery.menalto.com/forum_module_captionator"

View File

@ -0,0 +1,68 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<div id="g-captionator-dialog">
<script type="text/javascript">
$(document).ready(function() {
$('form input[name^=tags]').ready(function() {
$('form input[name^=tags]').gallery_autocomplete(
"<?= url::site("/tags/autocomplete") ?>",
{max: 30, multiple: true, multipleSeparator: ',', cacheLength: 1});
});
$('form input[name^=title]').change(function() {
var title = $(this).val();
slug = title.replace(/^\'/, "");
var slug = title.replace(/[^A-Za-z0-9-_]+/g, "-");
slug = slug.replace(/^-/, "");
slug = slug.replace(/-$/, "");
$(this).parent().parent().find("input[name^=internetaddress]").val(slug);
});
});
</script>
<form action="<?= url::site("captionator/save/{$album->id}") ?>" method="post" id="g-captionator-form">
<?= access::csrf_form_field() ?>
<fieldset>
<legend>
<?= t("Add captions for photos in <b>%album_title</b>", array("album_title" => $album->title)) ?>
</legend>
<? foreach ($album->viewable()->children() as $child): ?>
<table>
<tr>
<td style="width: 140px">
<?= $child->thumb_img(array(), 140, true) ?>
</td>
<td>
<ul>
<li>
<label for="title[<?= $child->id ?>]"> <?= t("Title") ?> </label>
<input required type="text" name="title[<?= $child->id ?>]" value="<?= html::chars($child->title) ?>"/>
</li>
<li>
<label for="description[<?= $child->id ?>]"> <?= t("Description") ?> </label>
<textarea style="height: 5em" name="description[<?= $child->id ?>]"><?= $child->description ?></textarea>
</li>
<? if ($enable_tags): ?>
<li>
<label for="tags[<?= $child->id ?>]"> <?= t("Tags (comma separated)") ?> </label>
<input type="text" name="tags[<?= $child->id ?>]" class="ac_input" autocomplete="off" value="<?= html::chars($tags[$child->id]) ?>"/>
</li>
<? endif ?>
<li>
<label for="filename[<?= $child->id ?>]"> <?= t("Filename") ?> </label>
<input type="text" name="filename[<?= $child->id ?>]" class="ac_input" autocomplete="off" value="<?= html::chars($child->name) ?>"/>
</li>
<li>
<label for="internetaddress[<?= $child->id ?>]"> <?= t("Internet Address") ?> </label>
<input type="text" name="internetaddress[<?= $child->id ?>]" class="ac_input" autocomplete="off" value="<?= html::chars($child->slug) ?>"/>
</li>
</ul>
</td>
</tr>
</table>
<? endforeach ?>
</fieldset>
<fieldset>
<input type="submit" name="cancel" value="<?= t("Cancel") ?>"/>
<input type="submit" name="save" value="<?= t("Save") ?>"/>
</fieldset>
</form>
</div>

View File

@ -0,0 +1,254 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2021 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 Admin_Custom_Menus_Controller extends Admin_Controller {
public function index() {
// Display the admin page, which contains a list of existing menu items.
$view = new Admin_View("admin.html");
$view->page_title = t("Manage menus");
$view->content = new View("admin_custom_menus.html");
$view->content->menu_list = $this->get_html_list(0);
print $view;
}
public function form_create($id) {
// Display the create new menu form.
print $this->get_new_menu_form($id);
}
public function form_edit($id) {
// Display the edit menu form.
print $this->get_edit_menu_form($id);
}
static function get_new_menu_form($id) {
// Generate the create new menu form.
$form = new Forge("admin/custom_menus/create/$id", "", "post", array("id" => "g-create-menu-form"));
$group = $form->group("create_menu")
->label(t("Add new menu"));
$group->input("menu_title")
->label(t("Title"));
$group->input("menu_url")
->label(t("URL (Leave blank if this menu will have sub-menus)"));
$group->submit("")->value(t("Create menu"));
return $form;
}
static function get_edit_menu_form($id) {
// Generate the edit menu form.
$existing_menu = ORM::factory("custom_menu", $id);
$form = new Forge("admin/custom_menus/edit/$id", "", "post", array("id" => "g-edit-menu-form"));
$group = $form->group("edit_menu")
->label(t("Edit menu"));
$group->input("menu_title")
->label(t("Title"))
->value($existing_menu->title);
$group->input("menu_url")
->label(t("URL (Leave blank if this menu will have sub-menus)"))
->value($existing_menu->url);
$group->submit("")->value(t("Save changes"));
return $form;
}
public function create($id) {
// Save a new menu to the database.
access::verify_csrf();
// Save form variables to the database.
$new_menu = ORM::factory("custom_menu");
$new_menu->title = Input::instance()->post("menu_title");
$new_menu->url = Input::instance()->post("menu_url");
$new_menu->parent_id = $id;
// Set menu's location to the last position.
$existing_menu = ORM::factory("custom_menu")
->where("parent_id", "=", $id)
->order_by("order_by", "DESC")
->find_all(1);
if (count($existing_menu) > 0) {
$int_position = $existing_menu[0]->order_by;
$int_position++;
$new_menu->order_by = $int_position;
} else {
$new_menu->order_by = 0;
}
// Save new menu to the database.
$new_menu->save();
message::success(t("Menu %menu_name created", array("menu_name" => $new_menu->title)));
log::success("custom_menus", t("Menu %menu_name created", array("menu_name" => $new_menu->title)));
json::reply(array("result" => "success"));
}
public function edit($id) {
// Save a new menu to the database.
access::verify_csrf();
// Load the existing menu and save changes.
$existing_menu = ORM::factory("custom_menu", $id);
if ($existing_menu->loaded()) {
$existing_menu->title = Input::instance()->post("menu_title");
$existing_menu->url = Input::instance()->post("menu_url");
$existing_menu->save();
message::success(t("Menu %menu_name saved", array("menu_name" => $existing_menu->title)));
log::success("custom_menus", t("Menu %menu_name saved", array("menu_name" => $existing_menu->title)));
json::reply(array("result" => "success"));
} else {
message::error(t("Unable to load menu %menu_id", array("menu_id" => $id)));
log::success("custom_menus", t("Unable to load menu %menu_id", array("menu_id" => $id)));
json::reply(array("result" => "success"));
}
}
function get_html_list($parent_id) {
// Generate an HTML list of existing menu items.
$existing_menu = ORM::factory("custom_menu")
->where("parent_id", "=", $parent_id)
->order_by("order_by", "ASC")
->find_all();
$str_html = "";
if (count($existing_menu) > 0) {
$str_html = "<ul style=\"margin-bottom: 0em; margin-left: 2.5em;\">\n";
foreach ($existing_menu as $one_menu) {
$str_html .= "<li style=\"list-style:disc outside none; margin: 1em; line-height: 1em;\">" . $one_menu->title .
" <a href=\"" . url::site("admin/custom_menus/form_create/" . $one_menu->id) .
"\" class=\"g-dialog-link ui-icon-plus g-button ui-icon-left\" title=\"" . t("Add sub menu") .
"\"><span class=\"ui-icon ui-icon-plus\"></span></a>" .
" <a href=\"" . url::site("admin/custom_menus/form_edit/" . $one_menu->id) .
"\" class=\"g-dialog-link ui-icon-pencil g-button ui-icon-left\" title=\"" . t("Edit menu") .
"\"><span class=\"ui-icon ui-icon-pencil\"></span></a>" .
" <a href=\"" . url::site("admin/custom_menus/form_delete/" . $one_menu->id) .
"\" class=\"g-dialog-link ui-icon-trash g-button ui-icon-left\" title=\"" . t("Delete menu") .
"\"><span class=\"ui-icon ui-icon-trash\"></span></a>" .
" <a href=\"" . url::site("admin/custom_menus/move_menu_up/" . $one_menu->id) .
"\" class=\"g-button ui-icon-left\" title=\"" . t("Move menu up") .
"\">^</a>" .
" <a href=\"" . url::site("admin/custom_menus/move_menu_down/" . $one_menu->id) .
"\" class=\"g-button ui-icon-left\" title=\"" . t("Move menu down") .
"\">v</a>" .
"</li>\n";
$str_html .= $this->get_html_list($one_menu->id);
}
$str_html .= "</ul>\n";
}
return $str_html;
}
public function form_delete($id) {
// Display a form asking the user if they want to delete a menu.
$one_menu = ORM::factory("custom_menu", $id);
if ($one_menu->loaded()) {
print $this->get_delete_form($one_menu);
}
}
public function delete($id) {
// Delete the specified menu.
access::verify_csrf();
// Make sure $id belongs to an actual menu.
$one_menu = ORM::factory("custom_menu", $id);
if (!$one_menu->loaded()) {
throw new Kohana_404_Exception();
}
// If the form validates, delete the specified menu.
$form = $this->get_delete_form($one_menu);
if ($form->validate()) {
$name = $one_menu->title;
$this->delete_sub_menus($one_menu->id);
$one_menu->delete();
message::success(t("Deleted menu %menu_name", array("menu_name" => $name)));
log::success("custom_menus", t("Deleted menu %menu_name", array("menu_name" => $name)));
json::reply(array("result" => "success", "location" => url::site("admin/custom_menus")));
} else {
print $form;
}
}
function delete_sub_menus($parent_id) {
// Delete all sub menus associated with $parent_id.
$existing_menu = ORM::factory("custom_menu")
->where("parent_id", "=", $parent_id)
->order_by("title", "ASC")
->find_all();
foreach ($existing_menu as $one_menu) {
$this->delete_sub_menus($one_menu->id);
$one_menu->delete();
}
}
static function get_delete_form($one_menu) {
// Generate a new form asking the user if they want to delete a menu.
$form = new Forge("admin/custom_menus/delete/$one_menu->id", "", "post", array("id" => "g-delete-menu-form"));
$group = $form->group("delete_menu")
->label(t("Really delete menu %menu_name & sub-menus?", array("menu_name" => $one_menu->title)));
$group->submit("")->value(t("Delete Menu"));
return $form;
}
public function move_menu_up($id) {
// Move the specified menu item up one position.
$one_menu = ORM::factory("custom_menu", $id);
if ($one_menu->loaded()) {
$existing_menu = ORM::factory("custom_menu")
->where("parent_id", "=", $one_menu->parent_id)
->where("order_by", "<", $one_menu->order_by)
->order_by("order_by", "DESC")
->find_all(1);
if (count($existing_menu) > 0) {
$second_menu = ORM::factory("custom_menu", $existing_menu[0]->id);
$temp_position = $one_menu->order_by;
$one_menu->order_by = $second_menu->order_by;
$second_menu->order_by = $temp_position;
$one_menu->save();
$second_menu->save();
message::success(t("Menu %menu_title moved up", array("menu_title" => $one_menu->title)));
log::success("custom_menus", t("Menu %menu_title moved up", array("menu_title" => $one_menu->title)));
}
}
url::redirect("admin/custom_menus");
}
public function move_menu_down($id) {
// Move the specified menu item down one position.
$one_menu = ORM::factory("custom_menu", $id);
if ($one_menu->loaded()) {
$existing_menu = ORM::factory("custom_menu")
->where("parent_id", "=", $one_menu->parent_id)
->where("order_by", ">", $one_menu->order_by)
->order_by("order_by", "ASC")
->find_all(1);
if (count($existing_menu) > 0) {
$second_menu = ORM::factory("custom_menu", $existing_menu[0]->id);
$temp_position = $one_menu->order_by;
$one_menu->order_by = $second_menu->order_by;
$second_menu->order_by = $temp_position;
$one_menu->save();
$second_menu->save();
message::success(t("Menu %menu_title moved down", array("menu_title" => $one_menu->title)));
log::success("custom_menus", t("Menu %menu_title moved down", array("menu_title" => $one_menu->title)));
}
}
url::redirect("admin/custom_menus");
}
}

View File

@ -0,0 +1,75 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2021 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 custom_menus_event_Core {
static function admin_menu($menu, $theme) {
// Add a settings link to the admin menu.
$menu->get("content_menu")
->append(Menu::factory("link")
->id("custom_menus")
->label(t("Custom Menus Manager"))
->url(url::site("admin/custom_menus")));
}
static function site_menu($menu, $theme) {
// Add user definied menu and sub-menu items to the site menu.
$existing_menu = ORM::factory("custom_menu")
->where("parent_id", "=", "0")
->order_by("order_by", "DESC")
->find_all();
if (count($existing_menu) > 0) {
foreach ($existing_menu as $one_menu) {
if ($one_menu->url == "") {
$menu->add_after("home", $new_menu = Menu::factory("submenu")
->id("custom_menus-" . $one_menu->id)
->label(t($one_menu->title)));
custom_menus_event::add_sub_menus($one_menu->id, $new_menu);
} else {
$menu->add_after("home", Menu::factory("link")
->id("custom_menus-" . $one_menu->id)
->label(t($one_menu->title))
->url($one_menu->url));
}
}
}
}
function add_sub_menus($parent_id, $parent_menu) {
// Populate the menu bar with any sub-menu items on the current menu ($parent_menu).
$existing_menu = ORM::factory("custom_menu")
->where("parent_id", "=", $parent_id)
->order_by("order_by", "ASC")
->find_all();
if (count($existing_menu) > 0) {
foreach ($existing_menu as $one_menu) {
if ($one_menu->url == "") {
$parent_menu->append($new_menu = Menu::factory("submenu")
->id("custom_menus-" . $one_menu->id)
->label(t($one_menu->title)));
custom_menus_event::add_sub_menus($one_menu->id, $new_menu);
} else {
$parent_menu->append(Menu::factory("link")
->id("custom_menus-" . $one_menu->id)
->label(t($one_menu->title))
->url($one_menu->url));
}
}
}
}
}

View File

@ -0,0 +1,37 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2021 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 custom_menus_installer {
static function install() {
// Create a table to store menu info in.
$db = Database::instance();
$db->query("CREATE TABLE IF NOT EXISTS {custom_menus} (
`id` int(9) NOT NULL auto_increment,
`title` varchar(255) default NULL,
`url` text default NULL,
`parent_id` int(9) NOT NULL default 0,
`order_by` int(9) NOT NULL default 0,
PRIMARY KEY (`id`),
UNIQUE KEY(`id`))
DEFAULT CHARSET=utf8;");
// Set the module version number.
module::set_version("custom_menus", 1);
}
}

View File

@ -0,0 +1,21 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2021 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 Custom_Menu_Model extends ORM {
}

View File

@ -0,0 +1,7 @@
name = "Custom Menus"
description = "Allows Gallery admins to create additional menu and sub-menu items."
version = 1
author_name = "rWatcher"
author_url = "http://codex.gallery2.org/User:RWatcher"
info_url = "https://gallery3-contrib.gitlab.io/#Documentation:27018362"
discuss_url = "https://gitlab.com/eric2001/custom_menus/-/issues"

View File

@ -0,0 +1,8 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<div class="g-block">
<h1> <?= t("Manage menus") ?> </h1>
<div class="g-block-content">
<a href="<?= url::site("admin/custom_menus/form_create/0") ?>" class="g-dialog-link g-create-link"><?= t("Add new menu") ?></a>
<?= $menu_list ?>
</div>
</div>

View File

@ -0,0 +1,36 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2021 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 database_info_block_Core {
static function get_admin_list() {
return array("database_info" => t("Database info"));
}
static function get($block_id) {
$block = new Block();
switch ($block_id) {
case "database_info":
$block->css_id = "g-database-info";
$block->title = t("Database information");
$block->content = new View("admin_block_db.html");
break;
}
return $block;
}
}

View File

@ -0,0 +1,7 @@
name = "Database Info"
description = "View information about your Gallery 3 database on the admin dashboard."
version = 1
author_name = "rWatcher"
author_url = "http://codex.gallery2.org/User:RWatcher"
info_url = "https://gallery3-contrib.gitlab.io/#Documentation:27018364"
discuss_url = "https://gitlab.com/eric2001/database_info/-/issues"

View File

@ -0,0 +1,18 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<?php
$db = Database::instance();
$tables = $db->query("SHOW TABLE STATUS");
$database_size = 0;
foreach($tables as $table) {
$database_size += ($table->Data_length + $table->Index_length);
}
$database_size = $database_size / 1024 / 1024;
?>
<ul>
<li>
<?= t("Database size: %dbsize MB", array("dbsize" => number_format($database_size, 2))) ?>
</li>
<li>
<?= t("Number of tables: %dbtables", array("dbtables" => count($tables))) ?>
</li>
</ul>

View File

@ -0,0 +1,70 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2013 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 delete_cache_task_Core {
static function available_tasks() {
return array(Task_Definition::factory()
->callback("delete_cache_task::delete_cache")
->name(t("Delete cache"))
->description(t("Truncate the cache table from the database."))
->severity(log::SUCCESS),
);
}
static function delete_cache($task) {
$start = microtime(true);
$total = $task->get("total");
if (empty($total)) {
$task->set("total", $total = db::build()->count_records("caches"));
$task->set("last_id", 0);
$task->set("completed", 0);
}
$last_id = $task->get("last_id");
$completed = $task->get("completed");
foreach (ORM::factory("cache")
->where("id", ">", $last_id)
->find_all(100) as $item) {
$last_id = $item->id;
$completed++;
if ($completed == $total || microtime(true) - $start > 1.5) {
break;
}
}
$task->set("completed", $completed);
$task->set("last_id", $last_id);
if ($total == $completed) {
$task->done = true;
$task->state = "success";
$task->percent_complete = 100;
$db = Database::instance();
$db->query("TRUNCATE TABLE {caches}");
} else {
$task->percent_complete = round(100 * $completed / $total);
}
$task->status = t2("One row updated", "%count / %total rows truncated from the cache table", $completed,
array("total" => $total));
}
}

View File

@ -0,0 +1,7 @@
name = "Delete cache"
description = "Delete various caches in your gallery install database"
version = 1
author_name = "floridave"
author_url = ""
info_url = "http://codex.gallery2.org/Gallery3:Modules:delete_cache"
discuss_url = "http://gallery.menalto.com/forum_module_delete_cache"

View File

@ -0,0 +1,93 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2021 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 Admin_DownloadFullsize_Controller extends Admin_Controller {
public function index() {
// Generate a new admin page.
$view = new Admin_View("admin.html");
$view->content = new View("admin_downloadfullsize.html");
$view->content->downloadlinks_form = $this->_get_admin_form();
print $view;
}
public function saveprefs() {
// Prevent Cross Site Request Forgery
access::verify_csrf();
// Figure out which boxes where checked
$dlLinks_array = Input::instance()->post("DownloadLinkOptions");
$fButton = false;
$download_original_button = false;
for ($i = 0; $i < count($dlLinks_array); $i++) {
if ($dlLinks_array[$i] == "fButton") {
$fButton = true;
}
}
if (module::is_active("keeporiginal")) {
$keeporiginal_array = Input::instance()->post("DownloadOriginalOptions");
for ($i = 0; $i < count($keeporiginal_array); $i++) {
if ($keeporiginal_array[$i] == "DownloadOriginalImage") {
$download_original_button = true;
}
}
module::set_var("downloadfullsize", "DownloadOriginalImage", $download_original_button);
}
// Save Settings.
module::set_var("downloadfullsize", "fButton", $fButton);
message::success(t("Your Selection Has Been Saved."));
// Load Admin page.
$view = new Admin_View("admin.html");
$view->content = new View("admin_downloadfullsize.html");
$view->content->downloadlinks_form = $this->_get_admin_form();
print $view;
}
private function _get_admin_form() {
// Make a new Form.
$form = new Forge("admin/downloadfullsize/saveprefs", "", "post",
array("id" => "g-download-fullsize-adminForm"));
// Make an array for the different types of download links.
$linkOptions["fButton"] = array(t("Show Floppy Disk Picture Link"), module::get_var("downloadfullsize", "fButton"));
// Setup a few checkboxes on the form.
$add_links = $form->group("DownloadLinks");
$add_links->checklist("DownloadLinkOptions")
->options($linkOptions);
if (module::is_active("keeporiginal")) {
$KeepOriginalOptions["DownloadOriginalImage"] = array(t("Allow visitors to download the original image when available?"), module::get_var("downloadfullsize", "DownloadOriginalImage"));
$keeporiginal_group = $form->group("KeepOriginalPrefs")
->label(t("KeepOriginal Preferences"));
$keeporiginal_group->checklist("DownloadOriginalOptions")
->options($KeepOriginalOptions);
}
// Add a save button to the form.
$form->submit("SaveLinks")->value(t("Save"));
// Return the newly generated form.
return $form;
}
}

View File

@ -0,0 +1,37 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2021 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 downloadfullsize_Controller extends Controller {
public function send($id) {
$item = ORM::factory("item", $id);
access::required("view_full", $item);
if (module::is_active("keeporiginal") && $item->is_photo() && module::get_var("downloadfullsize", "DownloadOriginalImage")) {
$original_image = VARPATH . "original/" . str_replace(VARPATH . "albums/", "", $item->file_path());
if (file_exists($original_image)) {
download::force($original_image);
} else {
download::force($item->file_path());
}
} else {
download::force($item->file_path());
}
}
}

View File

@ -0,0 +1,3 @@
#g-view-menu #g-download-fullsize-link {
background-image: url('../images/ico-view-downloadfullsize.png');
}

View File

@ -0,0 +1,51 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2021 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 downloadfullsize_block_Core {
static function get_site_list() {
return array("downloadfullsize" => t("Download Item"));
}
static function get($block_id, $theme) {
$item = $theme->item;
switch ($block_id) {
case "downloadfullsize":
// If Item is movie then...
if ($item && $item->is_movie() && access::can("view_full", $item)) {
$block = new Block();
$block->css_id = "g-download-fullsize";
$block->title = t("Download Movie");
$block->content = new View("downloadfullsize_block.html");
return $block;
}
// If Item is photo then...
if ($item && $item->is_photo() && access::can("view_full", $item)) {
$block = new Block();
$block->css_id = "g-download-fullsize";
$block->title = t("Download Photo");
$block->content = new View("downloadfullsize_block.html");
return $block;
}
}
return "";
}
}

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