diff options
author | Nathan Kinkade <nkinkade@nkinka.de> | 2010-09-01 17:40:01 +0000 |
---|---|---|
committer | Nathan Kinkade <nkinkade@nkinka.de> | 2010-09-01 17:40:01 +0000 |
commit | 538df03dd14f93419209ef61107a674575828e25 (patch) | |
tree | f5874b59fa616d538abaf08f9c9bf61724788bba | |
parent | 940f9330efca76c84e7a645cafc93acd2751a225 (diff) | |
parent | 78c590ebaee738435260e3b0bf6cb8fb5431a08d (diff) |
Manually merged changes to .htaccess file resolving conflicts due to my changes of the file.
54 files changed, 454 insertions, 1574 deletions
@@ -66,4 +66,5 @@ RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?kohana_uri=$1 [QSA,PT,L] RewriteRule ^$ index.php?kohana_uri=$1 [QSA,PT,L] + RewriteRule ^index.php/(.*) $1 [QSA,R,L] </IfModule> diff --git a/installer/install.css b/installer/install.css index 513d502f..e132b80d 100644 --- a/installer/install.css +++ b/installer/install.css @@ -4,10 +4,14 @@ h1, h2, h3 { body { background: #eee; - font-family: Trebuchet MS; + font-family: Trebuchet MS, Verdana; font-size: 1.1em; } +em { + font-style: italic; +} + div#outer { width: 650px; background: white; @@ -47,11 +51,14 @@ fieldset { border: 0px; padding-left: 0px; margin-top: 1em; + border: 1px solid #ccc; + padding: 8px; } fieldset legend { font-weight: bold; - padding-left: 0px; + margin: 8px; + padding: 2px; } table#db_info { @@ -66,6 +73,9 @@ code { background: #eee; border: 1px solid #bbb; padding: 2px; + display: block; + width: 200px; + margin: 4px 4px 4px 20px; } code.location { @@ -74,3 +84,9 @@ code.location { padding: 4px; width: auto; } + +span.subtext { + font-size: .7em; + color: #999; +} + diff --git a/installer/install.sql b/installer/install.sql index c6314aa7..7440cc8f 100644 --- a/installer/install.sql +++ b/installer/install.sql @@ -244,10 +244,10 @@ CREATE TABLE {modules} ( KEY `weight` (`weight`) ) AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -INSERT INTO {modules} VALUES (1,1,'gallery',34,1); +INSERT INTO {modules} VALUES (1,1,'gallery',37,1); INSERT INTO {modules} VALUES (2,1,'user',3,2); INSERT INTO {modules} VALUES (3,1,'comment',3,3); -INSERT INTO {modules} VALUES (4,1,'organize',1,4); +INSERT INTO {modules} VALUES (4,1,'organize',2,4); INSERT INTO {modules} VALUES (5,1,'info',1,5); INSERT INTO {modules} VALUES (6,1,'rest',3,6); INSERT INTO {modules} VALUES (7,1,'rss',1,7); @@ -395,7 +395,7 @@ CREATE TABLE {vars} ( `value` text, PRIMARY KEY (`id`), UNIQUE KEY `module_name` (`module_name`,`name`) -) AUTO_INCREMENT=43 DEFAULT CHARSET=utf8; +) AUTO_INCREMENT=49 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO {vars} VALUES (NULL,'gallery','active_site_theme','wind'); INSERT INTO {vars} VALUES (NULL,'gallery','active_admin_theme','admin_wind'); @@ -412,10 +412,16 @@ INSERT INTO {vars} VALUES (NULL,'gallery','simultaneous_upload_limit','5'); INSERT INTO {vars} VALUES (NULL,'gallery','admin_area_timeout','5400'); INSERT INTO {vars} VALUES (NULL,'gallery','maintenance_mode','0'); INSERT INTO {vars} VALUES (NULL,'gallery','blocks_dashboard_sidebar','a:4:{i:2;a:2:{i:0;s:7:\"gallery\";i:1;s:11:\"block_adder\";}i:3;a:2:{i:0;s:7:\"gallery\";i:1;s:5:\"stats\";}i:4;a:2:{i:0;s:7:\"gallery\";i:1;s:13:\"platform_info\";}i:5;a:2:{i:0;s:7:\"gallery\";i:1;s:12:\"project_news\";}}'); +INSERT INTO {vars} VALUES (NULL,'gallery','visible_title_length','15'); INSERT INTO {vars} VALUES (NULL,'gallery','date_time_format','Y-M-d H:i:s'); +INSERT INTO {vars} VALUES (NULL,'gallery','favicon_url','lib/images/favicon.ico'); INSERT INTO {vars} VALUES (NULL,'gallery','date_format','Y-M-d'); INSERT INTO {vars} VALUES (NULL,'gallery','blocks_dashboard_center','a:3:{i:6;a:2:{i:0;s:7:\"gallery\";i:1;s:7:\"welcome\";}i:7;a:2:{i:0;s:7:\"gallery\";i:1;s:12:\"photo_stream\";}i:8;a:2:{i:0;s:7:\"gallery\";i:1;s:11:\"log_entries\";}}'); +INSERT INTO {vars} VALUES (NULL,'gallery','email_from','admin@example.com'); +INSERT INTO {vars} VALUES (NULL,'gallery','email_reply_to','public@example.com'); INSERT INTO {vars} VALUES (NULL,'gallery','choose_default_tookit','1'); +INSERT INTO {vars} VALUES (NULL,'gallery','email_line_length','70'); +INSERT INTO {vars} VALUES (NULL,'gallery','email_header_separator','s:1:\"\n\";'); INSERT INTO {vars} VALUES (NULL,'comment','access_permissions','everybody'); INSERT INTO {vars} VALUES (NULL,'gallery','blocks_site_sidebar','a:4:{i:9;a:2:{i:0;s:7:\"gallery\";i:1;s:8:\"language\";}i:10;a:2:{i:0;s:4:\"info\";i:1;s:8:\"metadata\";}i:11;a:2:{i:0;s:3:\"rss\";i:1;s:9:\"rss_feeds\";}i:12;a:2:{i:0;s:3:\"tag\";i:1;s:3:\"tag\";}}'); INSERT INTO {vars} VALUES (NULL,'gallery','identity_provider','user'); diff --git a/installer/views/get_db_info.html.php b/installer/views/get_db_info.html.php index ada0793c..9fc1accd 100644 --- a/installer/views/get_db_info.html.php +++ b/installer/views/get_db_info.html.php @@ -1,25 +1,27 @@ <?php defined("SYSPATH") or die("No direct script access.") ?> -<h1> Welcome! </h1> +<h1> Let's get going! </h1> <p> - Installing Gallery is very easy. We just need to know how to talk - to your MySQL database, and we need a place to store your photos on - your web host. + Installing Gallery is easy. We just need a place to put your photos + and info about your MySQL database. </p> -<fieldset> +<fieldset class="<?= installer::var_writable() ? 'success' : 'error' ?>"> <legend>Photo Storage</legend> <?php if (!installer::var_writable()): ?> - <p class="error"> + <p> We're having trouble creating a place for your photos. Can you - help? Please create a directory called "var" using <code>mkdir var</code> in your - gallery3 directory, then run <code>chmod 777 var</code>. That - should fix it. - <br/><br/> + help? We need you to create a directory called <em>var</em> in + your gallery3 directory. This sample code works for most users. + Run it in the gallery3 directory: + <code> + mkdir var<br> + chmod 777 var + </code> <a href="index.php">Check again</a> </p> <?php else: ?> - <p class="success"> + <p> We've found a place to store your photos: <code class="location"> <?= VARPATH ?> </code> </p> @@ -31,14 +33,14 @@ <fieldset> <legend>Database</legend> <p> - We've provided values that work for most common web hosts. If - you have problems, contact your web host for help. + Gallery 3 needs a MySQL database. The values provided work for + most setups, so if you're confused try clicking <i>continue</i>. </p> <br/> <table id="db_info"> <tr> <td> - Database Name + Database name </td> <td> <input name="dbname" value="gallery3"/> @@ -70,7 +72,7 @@ </tr> <tr> <td> - Table Prefix + Table prefix <span class="subtext">(optional)</span> </td> <td> <input name="prefix" value=""/> diff --git a/lib/gallery.dialog.js b/lib/gallery.dialog.js index 450f4c88..ec187186 100644 --- a/lib/gallery.dialog.js +++ b/lib/gallery.dialog.js @@ -18,6 +18,9 @@ var self = this; var eDialog = '<div id="g-dialog"></div>'; + if ($("#g-dialog").length) { + $("#g-dialog").dialog("close"); + } $("body").append(eDialog); if (!self.options.close) { diff --git a/lib/swfupload/swfupload.js b/lib/swfupload/swfupload.js deleted file mode 100644 index e65b19cb..00000000 --- a/lib/swfupload/swfupload.js +++ /dev/null @@ -1,980 +0,0 @@ -/** - * SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com - * - * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/, http://www.vinterwebb.se/ - * - * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilzén and Mammon Media and is released under the MIT License: - * http://www.opensource.org/licenses/mit-license.php - * - * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License: - * http://www.opensource.org/licenses/mit-license.php - * - */ - - -/* ******************* */ -/* Constructor & Init */ -/* ******************* */ -var SWFUpload; - -if (SWFUpload == undefined) { - SWFUpload = function (settings) { - this.initSWFUpload(settings); - }; -} - -SWFUpload.prototype.initSWFUpload = function (settings) { - try { - this.customSettings = {}; // A container where developers can place their own settings associated with this instance. - this.settings = settings; - this.eventQueue = []; - this.movieName = "SWFUpload_" + SWFUpload.movieCount++; - this.movieElement = null; - - - // Setup global control tracking - SWFUpload.instances[this.movieName] = this; - - // Load the settings. Load the Flash movie. - this.initSettings(); - this.loadFlash(); - this.displayDebugInfo(); - } catch (ex) { - delete SWFUpload.instances[this.movieName]; - throw ex; - } -}; - -/* *************** */ -/* Static Members */ -/* *************** */ -SWFUpload.instances = {}; -SWFUpload.movieCount = 0; -SWFUpload.version = "2.2.0 2009-03-25"; -SWFUpload.QUEUE_ERROR = { - QUEUE_LIMIT_EXCEEDED : -100, - FILE_EXCEEDS_SIZE_LIMIT : -110, - ZERO_BYTE_FILE : -120, - INVALID_FILETYPE : -130 -}; -SWFUpload.UPLOAD_ERROR = { - HTTP_ERROR : -200, - MISSING_UPLOAD_URL : -210, - IO_ERROR : -220, - SECURITY_ERROR : -230, - UPLOAD_LIMIT_EXCEEDED : -240, - UPLOAD_FAILED : -250, - SPECIFIED_FILE_ID_NOT_FOUND : -260, - FILE_VALIDATION_FAILED : -270, - FILE_CANCELLED : -280, - UPLOAD_STOPPED : -290 -}; -SWFUpload.FILE_STATUS = { - QUEUED : -1, - IN_PROGRESS : -2, - ERROR : -3, - COMPLETE : -4, - CANCELLED : -5 -}; -SWFUpload.BUTTON_ACTION = { - SELECT_FILE : -100, - SELECT_FILES : -110, - START_UPLOAD : -120 -}; -SWFUpload.CURSOR = { - ARROW : -1, - HAND : -2 -}; -SWFUpload.WINDOW_MODE = { - WINDOW : "window", - TRANSPARENT : "transparent", - OPAQUE : "opaque" -}; - -// Private: takes a URL, determines if it is relative and converts to an absolute URL -// using the current site. Only processes the URL if it can, otherwise returns the URL untouched -SWFUpload.completeURL = function(url) { - if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || url.match(/^\//)) { - return url; - } - - var currentURL = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port : ""); - - var indexSlash = window.location.pathname.lastIndexOf("/"); - if (indexSlash <= 0) { - path = "/"; - } else { - path = window.location.pathname.substr(0, indexSlash) + "/"; - } - - return /*currentURL +*/ path + url; - -}; - - -/* ******************** */ -/* Instance Members */ -/* ******************** */ - -// Private: initSettings ensures that all the -// settings are set, getting a default value if one was not assigned. -SWFUpload.prototype.initSettings = function () { - this.ensureDefault = function (settingName, defaultValue) { - this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName]; - }; - - // Upload backend settings - this.ensureDefault("upload_url", ""); - this.ensureDefault("preserve_relative_urls", false); - this.ensureDefault("file_post_name", "Filedata"); - this.ensureDefault("post_params", {}); - this.ensureDefault("use_query_string", false); - this.ensureDefault("requeue_on_error", false); - this.ensureDefault("http_success", []); - this.ensureDefault("assume_success_timeout", 0); - - // File Settings - this.ensureDefault("file_types", "*.*"); - this.ensureDefault("file_types_description", "All Files"); - this.ensureDefault("file_size_limit", 0); // Default zero means "unlimited" - this.ensureDefault("file_upload_limit", 0); - this.ensureDefault("file_queue_limit", 0); - - // Flash Settings - this.ensureDefault("flash_url", "swfupload.swf"); - this.ensureDefault("prevent_swf_caching", true); - - // Button Settings - this.ensureDefault("button_image_url", ""); - this.ensureDefault("button_width", 1); - this.ensureDefault("button_height", 1); - this.ensureDefault("button_text", ""); - this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;"); - this.ensureDefault("button_text_top_padding", 0); - this.ensureDefault("button_text_left_padding", 0); - this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES); - this.ensureDefault("button_disabled", false); - this.ensureDefault("button_placeholder_id", ""); - this.ensureDefault("button_placeholder", null); - this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW); - this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW); - - // Debug Settings - this.ensureDefault("debug", false); - this.settings.debug_enabled = this.settings.debug; // Here to maintain v2 API - - // Event Handlers - this.settings.return_upload_start_handler = this.returnUploadStart; - this.ensureDefault("swfupload_loaded_handler", null); - this.ensureDefault("file_dialog_start_handler", null); - this.ensureDefault("file_queued_handler", null); - this.ensureDefault("file_queue_error_handler", null); - this.ensureDefault("file_dialog_complete_handler", null); - - this.ensureDefault("upload_start_handler", null); - this.ensureDefault("upload_progress_handler", null); - this.ensureDefault("upload_error_handler", null); - this.ensureDefault("upload_success_handler", null); - this.ensureDefault("upload_complete_handler", null); - - this.ensureDefault("debug_handler", this.debugMessage); - - this.ensureDefault("custom_settings", {}); - - // Other settings - this.customSettings = this.settings.custom_settings; - - // Update the flash url if needed - if (!!this.settings.prevent_swf_caching) { - this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime(); - } - - if (!this.settings.preserve_relative_urls) { - //this.settings.flash_url = SWFUpload.completeURL(this.settings.flash_url); // Don't need to do this one since flash doesn't look at it - this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url); - this.settings.button_image_url = SWFUpload.completeURL(this.settings.button_image_url); - } - - delete this.ensureDefault; -}; - -// Private: loadFlash replaces the button_placeholder element with the flash movie. -SWFUpload.prototype.loadFlash = function () { - var targetElement, tempParent; - - // Make sure an element with the ID we are going to use doesn't already exist - if (document.getElementById(this.movieName) !== null) { - throw "ID " + this.movieName + " is already in use. The Flash Object could not be added"; - } - - // Get the element where we will be placing the flash movie - targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder; - - if (targetElement == undefined) { - throw "Could not find the placeholder element: " + this.settings.button_placeholder_id; - } - - // Append the container and load the flash - tempParent = document.createElement("div"); - tempParent.innerHTML = this.getFlashHTML(); // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers) - targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement); - - // Fix IE Flash/Form bug - if (window[this.movieName] == undefined) { - window[this.movieName] = this.getMovieElement(); - } - -}; - -// Private: getFlashHTML generates the object tag needed to embed the flash in to the document -SWFUpload.prototype.getFlashHTML = function () { - // Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay - return ['<object id="', this.movieName, '" type="application/x-shockwave-flash" data="', this.settings.flash_url, '" width="', this.settings.button_width, '" height="', this.settings.button_height, '" class="swfupload">', - '<param name="wmode" value="', this.settings.button_window_mode, '" />', - '<param name="movie" value="', this.settings.flash_url, '" />', - '<param name="quality" value="high" />', - '<param name="menu" value="false" />', - '<param name="allowScriptAccess" value="always" />', - '<param name="flashvars" value="' + this.getFlashVars() + '" />', - '</object>'].join(""); -}; - -// Private: getFlashVars builds the parameter string that will be passed -// to flash in the flashvars param. -SWFUpload.prototype.getFlashVars = function () { - // Build a string from the post param object - var paramString = this.buildParamString(); - var httpSuccessString = this.settings.http_success.join(","); - - // Build the parameter string - return ["movieName=", encodeURIComponent(this.movieName), - "&uploadURL=", encodeURIComponent(this.settings.upload_url), - "&useQueryString=", encodeURIComponent(this.settings.use_query_string), - "&requeueOnError=", encodeURIComponent(this.settings.requeue_on_error), - "&httpSuccess=", encodeURIComponent(httpSuccessString), - "&assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout), - "&params=", encodeURIComponent(paramString), - "&filePostName=", encodeURIComponent(this.settings.file_post_name), - "&fileTypes=", encodeURIComponent(this.settings.file_types), - "&fileTypesDescription=", encodeURIComponent(this.settings.file_types_description), - "&fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit), - "&fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit), - "&fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit), - "&debugEnabled=", encodeURIComponent(this.settings.debug_enabled), - "&buttonImageURL=", encodeURIComponent(this.settings.button_image_url), - "&buttonWidth=", encodeURIComponent(this.settings.button_width), - "&buttonHeight=", encodeURIComponent(this.settings.button_height), - "&buttonText=", encodeURIComponent(this.settings.button_text), - "&buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding), - "&buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding), - "&buttonTextStyle=", encodeURIComponent(this.settings.button_text_style), - "&buttonAction=", encodeURIComponent(this.settings.button_action), - "&buttonDisabled=", encodeURIComponent(this.settings.button_disabled), - "&buttonCursor=", encodeURIComponent(this.settings.button_cursor) - ].join(""); -}; - -// Public: getMovieElement retrieves the DOM reference to the Flash element added by SWFUpload -// The element is cached after the first lookup -SWFUpload.prototype.getMovieElement = function () { - if (this.movieElement == undefined) { - this.movieElement = document.getElementById(this.movieName); - } - - if (this.movieElement === null) { - throw "Could not find Flash element"; - } - - return this.movieElement; -}; - -// Private: buildParamString takes the name/value pairs in the post_params setting object -// and joins them up in to a string formatted "name=value&name=value" -SWFUpload.prototype.buildParamString = function () { - var postParams = this.settings.post_params; - var paramStringPairs = []; - - if (typeof(postParams) === "object") { - for (var name in postParams) { - if (postParams.hasOwnProperty(name)) { - paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString())); - } - } - } - - return paramStringPairs.join("&"); -}; - -// Public: Used to remove a SWFUpload instance from the page. This method strives to remove -// all references to the SWF, and other objects so memory is properly freed. -// Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state. -// Credits: Major improvements provided by steffen -SWFUpload.prototype.destroy = function () { - try { - // Make sure Flash is done before we try to remove it - this.cancelUpload(null, false); - - - // Remove the SWFUpload DOM nodes - var movieElement = null; - movieElement = this.getMovieElement(); - - if (movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE - // Loop through all the movie's properties and remove all function references (DOM/JS IE 6/7 memory leak workaround) - for (var i in movieElement) { - try { - if (typeof(movieElement[i]) === "function") { - movieElement[i] = null; - } - } catch (ex1) {} - } - - // Remove the Movie Element from the page - try { - movieElement.parentNode.removeChild(movieElement); - } catch (ex) {} - } - - // Remove IE form fix reference - window[this.movieName] = null; - - // Destroy other references - SWFUpload.instances[this.movieName] = null; - delete SWFUpload.instances[this.movieName]; - - this.movieElement = null; - this.settings = null; - this.customSettings = null; - this.eventQueue = null; - this.movieName = null; - - - return true; - } catch (ex2) { - return false; - } -}; - - -// Public: displayDebugInfo prints out settings and configuration -// information about this SWFUpload instance. -// This function (and any references to it) can be deleted when placing -// SWFUpload in production. -SWFUpload.prototype.displayDebugInfo = function () { - this.debug( - [ - "---SWFUpload Instance Info---\n", - "Version: ", SWFUpload.version, "\n", - "Movie Name: ", this.movieName, "\n", - "Settings:\n", - "\t", "upload_url: ", this.settings.upload_url, "\n", - "\t", "flash_url: ", this.settings.flash_url, "\n", - "\t", "use_query_string: ", this.settings.use_query_string.toString(), "\n", - "\t", "requeue_on_error: ", this.settings.requeue_on_error.toString(), "\n", - "\t", "http_success: ", this.settings.http_success.join(", "), "\n", - "\t", "assume_success_timeout: ", this.settings.assume_success_timeout, "\n", - "\t", "file_post_name: ", this.settings.file_post_name, "\n", - "\t", "post_params: ", this.settings.post_params.toString(), "\n", - "\t", "file_types: ", this.settings.file_types, "\n", - "\t", "file_types_description: ", this.settings.file_types_description, "\n", - "\t", "file_size_limit: ", this.settings.file_size_limit, "\n", - "\t", "file_upload_limit: ", this.settings.file_upload_limit, "\n", - "\t", "file_queue_limit: ", this.settings.file_queue_limit, "\n", - "\t", "debug: ", this.settings.debug.toString(), "\n", - - "\t", "prevent_swf_caching: ", this.settings.prevent_swf_caching.toString(), "\n", - - "\t", "button_placeholder_id: ", this.settings.button_placeholder_id.toString(), "\n", - "\t", "button_placeholder: ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n", - "\t", "button_image_url: ", this.settings.button_image_url.toString(), "\n", - "\t", "button_width: ", this.settings.button_width.toString(), "\n", - "\t", "button_height: ", this.settings.button_height.toString(), "\n", - "\t", "button_text: ", this.settings.button_text.toString(), "\n", - "\t", "button_text_style: ", this.settings.button_text_style.toString(), "\n", - "\t", "button_text_top_padding: ", this.settings.button_text_top_padding.toString(), "\n", - "\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n", - "\t", "button_action: ", this.settings.button_action.toString(), "\n", - "\t", "button_disabled: ", this.settings.button_disabled.toString(), "\n", - - "\t", "custom_settings: ", this.settings.custom_settings.toString(), "\n", - "Event Handlers:\n", - "\t", "swfupload_loaded_handler assigned: ", (typeof this.settings.swfupload_loaded_handler === "function").toString(), "\n", - "\t", "file_dialog_start_handler assigned: ", (typeof this.settings.file_dialog_start_handler === "function").toString(), "\n", - "\t", "file_queued_handler assigned: ", (typeof this.settings.file_queued_handler === "function").toString(), "\n", - "\t", "file_queue_error_handler assigned: ", (typeof this.settings.file_queue_error_handler === "function").toString(), "\n", - "\t", "upload_start_handler assigned: ", (typeof this.settings.upload_start_handler === "function").toString(), "\n", - "\t", "upload_progress_handler assigned: ", (typeof this.settings.upload_progress_handler === "function").toString(), "\n", - "\t", "upload_error_handler assigned: ", (typeof this.settings.upload_error_handler === "function").toString(), "\n", - "\t", "upload_success_handler assigned: ", (typeof this.settings.upload_success_handler === "function").toString(), "\n", - "\t", "upload_complete_handler assigned: ", (typeof this.settings.upload_complete_handler === "function").toString(), "\n", - "\t", "debug_handler assigned: ", (typeof this.settings.debug_handler === "function").toString(), "\n" - ].join("") - ); -}; - -/* Note: addSetting and getSetting are no longer used by SWFUpload but are included - the maintain v2 API compatibility -*/ -// Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used. -SWFUpload.prototype.addSetting = function (name, value, default_value) { - if (value == undefined) { - return (this.settings[name] = default_value); - } else { - return (this.settings[name] = value); - } -}; - -// Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found. -SWFUpload.prototype.getSetting = function (name) { - if (this.settings[name] != undefined) { - return this.settings[name]; - } - - return ""; -}; - - - -// Private: callFlash handles function calls made to the Flash element. -// Calls are made with a setTimeout for some functions to work around -// bugs in the ExternalInterface library. -SWFUpload.prototype.callFlash = function (functionName, argumentArray) { - argumentArray = argumentArray || []; - - var movieElement = this.getMovieElement(); - var returnValue, returnString; - - // Flash's method if calling ExternalInterface methods (code adapted from MooTools). - try { - returnString = movieElement.CallFunction('<invoke name="' + functionName + '" returntype="javascript">' + __flash__argumentsToXML(argumentArray, 0) + '</invoke>'); - returnValue = eval(returnString); - } catch (ex) { - throw "Call to " + functionName + " failed"; - } - - // Unescape file post param values - if (returnValue != undefined && typeof returnValue.post === "object") { - returnValue = this.unescapeFilePostParams(returnValue); - } - - return returnValue; -}; - -/* ***************************** - -- Flash control methods -- - Your UI should use these - to operate SWFUpload - ***************************** */ - -// WARNING: this function does not work in Flash Player 10 -// Public: selectFile causes a File Selection Dialog window to appear. This -// dialog only allows 1 file to be selected. -SWFUpload.prototype.selectFile = function () { - this.callFlash("SelectFile"); -}; - -// WARNING: this function does not work in Flash Player 10 -// Public: selectFiles causes a File Selection Dialog window to appear/ This -// dialog allows the user to select any number of files -// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names. -// If the selection name length is too long the dialog will fail in an unpredictable manner. There is no work-around -// for this bug. -SWFUpload.prototype.selectFiles = function () { - this.callFlash("SelectFiles"); -}; - - -// Public: startUpload starts uploading the first file in the queue unless -// the optional parameter 'fileID' specifies the ID -SWFUpload.prototype.startUpload = function (fileID) { - this.callFlash("StartUpload", [fileID]); -}; - -// Public: cancelUpload cancels any queued file. The fileID parameter may be the file ID or index. -// If you do not specify a fileID the current uploading file or first file in the queue is cancelled. -// If you do not want the uploadError event to trigger you can specify false for the triggerErrorEvent parameter. -SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) { - if (triggerErrorEvent !== false) { - triggerErrorEvent = true; - } - this.callFlash("CancelUpload", [fileID, triggerErrorEvent]); -}; - -// Public: stopUpload stops the current upload and requeues the file at the beginning of the queue. -// If nothing is currently uploading then nothing happens. -SWFUpload.prototype.stopUpload = function () { - this.callFlash("StopUpload"); -}; - -/* ************************ - * Settings methods - * These methods change the SWFUpload settings. - * SWFUpload settings should not be changed directly on the settings object - * since many of the settings need to be passed to Flash in order to take - * effect. - * *********************** */ - -// Public: getStats gets the file statistics object. -SWFUpload.prototype.getStats = function () { - return this.callFlash("GetStats"); -}; - -// Public: setStats changes the SWFUpload statistics. You shouldn't need to -// change the statistics but you can. Changing the statistics does not -// affect SWFUpload accept for the successful_uploads count which is used -// by the upload_limit setting to determine how many files the user may upload. -SWFUpload.prototype.setStats = function (statsObject) { - this.callFlash("SetStats", [statsObject]); -}; - -// Public: getFile retrieves a File object by ID or Index. If the file is -// not found then 'null' is returned. -SWFUpload.prototype.getFile = function (fileID) { - if (typeof(fileID) === "number") { - return this.callFlash("GetFileByIndex", [fileID]); - } else { - return this.callFlash("GetFile", [fileID]); - } -}; - -// Public: addFileParam sets a name/value pair that will be posted with the -// file specified by the Files ID. If the name already exists then the -// exiting value will be overwritten. -SWFUpload.prototype.addFileParam = function (fileID, name, value) { - return this.callFlash("AddFileParam", [fileID, name, value]); -}; - -// Public: removeFileParam removes a previously set (by addFileParam) name/value -// pair from the specified file. -SWFUpload.prototype.removeFileParam = function (fileID, name) { - this.callFlash("RemoveFileParam", [fileID, name]); -}; - -// Public: setUploadUrl changes the upload_url setting. -SWFUpload.prototype.setUploadURL = function (url) { - this.settings.upload_url = url.toString(); - this.callFlash("SetUploadURL", [url]); -}; - -// Public: setPostParams changes the post_params setting -SWFUpload.prototype.setPostParams = function (paramsObject) { - this.settings.post_params = paramsObject; - this.callFlash("SetPostParams", [paramsObject]); -}; - -// Public: addPostParam adds post name/value pair. Each name can have only one value. -SWFUpload.prototype.addPostParam = function (name, value) { - this.settings.post_params[name] = value; - this.callFlash("SetPostParams", [this.settings.post_params]); -}; - -// Public: removePostParam deletes post name/value pair. -SWFUpload.prototype.removePostParam = function (name) { - delete this.settings.post_params[name]; - this.callFlash("SetPostParams", [this.settings.post_params]); -}; - -// Public: setFileTypes changes the file_types setting and the file_types_description setting -SWFUpload.prototype.setFileTypes = function (types, description) { - this.settings.file_types = types; - this.settings.file_types_description = description; - this.callFlash("SetFileTypes", [types, description]); -}; - -// Public: setFileSizeLimit changes the file_size_limit setting -SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) { - this.settings.file_size_limit = fileSizeLimit; - this.callFlash("SetFileSizeLimit", [fileSizeLimit]); -}; - -// Public: setFileUploadLimit changes the file_upload_limit setting -SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) { - this.settings.file_upload_limit = fileUploadLimit; - this.callFlash("SetFileUploadLimit", [fileUploadLimit]); -}; - -// Public: setFileQueueLimit changes the file_queue_limit setting -SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) { - this.settings.file_queue_limit = fileQueueLimit; - this.callFlash("SetFileQueueLimit", [fileQueueLimit]); -}; - -// Public: setFilePostName changes the file_post_name setting -SWFUpload.prototype.setFilePostName = function (filePostName) { - this.settings.file_post_name = filePostName; - this.callFlash("SetFilePostName", [filePostName]); -}; - -// Public: setUseQueryString changes the use_query_string setting -SWFUpload.prototype.setUseQueryString = function (useQueryString) { - this.settings.use_query_string = useQueryString; - this.callFlash("SetUseQueryString", [useQueryString]); -}; - -// Public: setRequeueOnError changes the requeue_on_error setting -SWFUpload.prototype.setRequeueOnError = function (requeueOnError) { - this.settings.requeue_on_error = requeueOnError; - this.callFlash("SetRequeueOnError", [requeueOnError]); -}; - -// Public: setHTTPSuccess changes the http_success setting -SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) { - if (typeof http_status_codes === "string") { - http_status_codes = http_status_codes.replace(" ", "").split(","); - } - - this.settings.http_success = http_status_codes; - this.callFlash("SetHTTPSuccess", [http_status_codes]); -}; - -// Public: setHTTPSuccess changes the http_success setting -SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) { - this.settings.assume_success_timeout = timeout_seconds; - this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]); -}; - -// Public: setDebugEnabled changes the debug_enabled setting -SWFUpload.prototype.setDebugEnabled = function (debugEnabled) { - this.settings.debug_enabled = debugEnabled; - this.callFlash("SetDebugEnabled", [debugEnabled]); -}; - -// Public: setButtonImageURL loads a button image sprite -SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) { - if (buttonImageURL == undefined) { - buttonImageURL = ""; - } - - this.settings.button_image_url = buttonImageURL; - this.callFlash("SetButtonImageURL", [buttonImageURL]); -}; - -// Public: setButtonDimensions resizes the Flash Movie and button -SWFUpload.prototype.setButtonDimensions = function (width, height) { - this.settings.button_width = width; - this.settings.button_height = height; - - var movie = this.getMovieElement(); - if (movie != undefined) { - movie.style.width = width + "px"; - movie.style.height = height + "px"; - } - - this.callFlash("SetButtonDimensions", [width, height]); -}; -// Public: setButtonText Changes the text overlaid on the button -SWFUpload.prototype.setButtonText = function (html) { - this.settings.button_text = html; - this.callFlash("SetButtonText", [html]); -}; -// Public: setButtonTextPadding changes the top and left padding of the text overlay -SWFUpload.prototype.setButtonTextPadding = function (left, top) { - this.settings.button_text_top_padding = top; - this.settings.button_text_left_padding = left; - this.callFlash("SetButtonTextPadding", [left, top]); -}; - -// Public: setButtonTextStyle changes the CSS used to style the HTML/Text overlaid on the button -SWFUpload.prototype.setButtonTextStyle = function (css) { - this.settings.button_text_style = css; - this.callFlash("SetButtonTextStyle", [css]); -}; -// Public: setButtonDisabled disables/enables the button -SWFUpload.prototype.setButtonDisabled = function (isDisabled) { - this.settings.button_disabled = isDisabled; - this.callFlash("SetButtonDisabled", [isDisabled]); -}; -// Public: setButtonAction sets the action that occurs when the button is clicked -SWFUpload.prototype.setButtonAction = function (buttonAction) { - this.settings.button_action = buttonAction; - this.callFlash("SetButtonAction", [buttonAction]); -}; - -// Public: setButtonCursor changes the mouse cursor displayed when hovering over the button -SWFUpload.prototype.setButtonCursor = function (cursor) { - this.settings.button_cursor = cursor; - this.callFlash("SetButtonCursor", [cursor]); -}; - -/* ******************************* - Flash Event Interfaces - These functions are used by Flash to trigger the various - events. - - All these functions a Private. - - Because the ExternalInterface library is buggy the event calls - are added to a queue and the queue then executed by a setTimeout. - This ensures that events are executed in a determinate order and that - the ExternalInterface bugs are avoided. -******************************* */ - -SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) { - // Warning: Don't call this.debug inside here or you'll create an infinite loop - - if (argumentArray == undefined) { - argumentArray = []; - } else if (!(argumentArray instanceof Array)) { - argumentArray = [argumentArray]; - } - - var self = this; - if (typeof this.settings[handlerName] === "function") { - // Queue the event - this.eventQueue.push(function () { - this.settings[handlerName].apply(this, argumentArray); - }); - - // Execute the next queued event - setTimeout(function () { - self.executeNextEvent(); - }, 0); - - } else if (this.settings[handlerName] !== null) { - throw "Event handler " + handlerName + " is unknown or is not a function"; - } -}; - -// Private: Causes the next event in the queue to be executed. Since events are queued using a setTimeout -// we must queue them in order to garentee that they are executed in order. -SWFUpload.prototype.executeNextEvent = function () { - // Warning: Don't call this.debug inside here or you'll create an infinite loop - - var f = this.eventQueue ? this.eventQueue.shift() : null; - if (typeof(f) === "function") { - f.apply(this); - } -}; - -// Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have -// properties that contain characters that are not valid for JavaScript identifiers. To work around this -// the Flash Component escapes the parameter names and we must unescape again before passing them along. -SWFUpload.prototype.unescapeFilePostParams = function (file) { - var reg = /[$]([0-9a-f]{4})/i; - var unescapedPost = {}; - var uk; - - if (file != undefined) { - for (var k in file.post) { - if (file.post.hasOwnProperty(k)) { - uk = k; - var match; - while ((match = reg.exec(uk)) !== null) { - uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16))); - } - unescapedPost[uk] = file.post[k]; - } - } - - file.post = unescapedPost; - } - - return file; -}; - -// Private: Called by Flash to see if JS can call in to Flash (test if External Interface is working) -SWFUpload.prototype.testExternalInterface = function () { - try { - return this.callFlash("TestExternalInterface"); - } catch (ex) { - return false; - } -}; - -// Private: This event is called by Flash when it has finished loading. Don't modify this. -// Use the swfupload_loaded_handler event setting to execute custom code when SWFUpload has loaded. -SWFUpload.prototype.flashReady = function () { - // Check that the movie element is loaded correctly with its ExternalInterface methods defined - var movieElement = this.getMovieElement(); - - if (!movieElement) { - this.debug("Flash called back ready but the flash movie can't be found."); - return; - } - - this.cleanUp(movieElement); - - this.queueEvent("swfupload_loaded_handler"); -}; - -// Private: removes Flash added fuctions to the DOM node to prevent memory leaks in IE. -// This function is called by Flash each time the ExternalInterface functions are created. -SWFUpload.prototype.cleanUp = function (movieElement) { - // Pro-actively unhook all the Flash functions - try { - if (this.movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE - this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)"); - for (var key in movieElement) { - try { - if (typeof(movieElement[key]) === "function") { - movieElement[key] = null; - } - } catch (ex) { - } - } - } - } catch (ex1) { - - } - - // Fix Flashes own cleanup code so if the SWFMovie was removed from the page - // it doesn't display errors. - window["__flash__removeCallback"] = function (instance, name) { - try { - if (instance) { - instance[name] = null; - } - } catch (flashEx) { - - } - }; - -}; - - -/* This is a chance to do something before the browse window opens */ -SWFUpload.prototype.fileDialogStart = function () { - this.queueEvent("file_dialog_start_handler"); -}; - - -/* Called when a file is successfully added to the queue. */ -SWFUpload.prototype.fileQueued = function (file) { - file = this.unescapeFilePostParams(file); - this.queueEvent("file_queued_handler", file); -}; - - -/* Handle errors that occur when an attempt to queue a file fails. */ -SWFUpload.prototype.fileQueueError = function (file, errorCode, message) { - file = this.unescapeFilePostParams(file); - this.queueEvent("file_queue_error_handler", [file, errorCode, message]); -}; - -/* Called after the file dialog has closed and the selected files have been queued. - You could call startUpload here if you want the queued files to begin uploading immediately. */ -SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) { - this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]); -}; - -SWFUpload.prototype.uploadStart = function (file) { - file = this.unescapeFilePostParams(file); - this.queueEvent("return_upload_start_handler", file); -}; - -SWFUpload.prototype.returnUploadStart = function (file) { - var returnValue; - if (typeof this.settings.upload_start_handler === "function") { - file = this.unescapeFilePostParams(file); - returnValue = this.settings.upload_start_handler.call(this, file); - } else if (this.settings.upload_start_handler != undefined) { - throw "upload_start_handler must be a function"; - } - - // Convert undefined to true so if nothing is returned from the upload_start_handler it is - // interpretted as 'true'. - if (returnValue === undefined) { - returnValue = true; - } - - returnValue = !!returnValue; - - this.callFlash("ReturnUploadStart", [returnValue]); -}; - - - -SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) { - file = this.unescapeFilePostParams(file); - this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]); -}; - -SWFUpload.prototype.uploadError = function (file, errorCode, message) { - file = this.unescapeFilePostParams(file); - this.queueEvent("upload_error_handler", [file, errorCode, message]); -}; - -SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) { - file = this.unescapeFilePostParams(file); - this.queueEvent("upload_success_handler", [file, serverData, responseReceived]); -}; - -SWFUpload.prototype.uploadComplete = function (file) { - file = this.unescapeFilePostParams(file); - this.queueEvent("upload_complete_handler", file); -}; - -/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the - internal debug console. You can override this event and have messages written where you want. */ -SWFUpload.prototype.debug = function (message) { - this.queueEvent("debug_handler", message); -}; - - -/* ********************************** - Debug Console - The debug console is a self contained, in page location - for debug message to be sent. The Debug Console adds - itself to the body if necessary. - - The console is automatically scrolled as messages appear. - - If you are using your own debug handler or when you deploy to production and - have debug disabled you can remove these functions to reduce the file size - and complexity. -********************************** */ - -// Private: debugMessage is the default debug_handler. If you want to print debug messages -// call the debug() function. When overriding the function your own function should -// check to see if the debug setting is true before outputting debug information. -SWFUpload.prototype.debugMessage = function (message) { - if (this.settings.debug) { - var exceptionMessage, exceptionValues = []; - - // Check for an exception object and print it nicely - if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") { - for (var key in message) { - if (message.hasOwnProperty(key)) { - exceptionValues.push(key + ": " + message[key]); - } - } - exceptionMessage = exceptionValues.join("\n") || ""; - exceptionValues = exceptionMessage.split("\n"); - exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: "); - SWFUpload.Console.writeLine(exceptionMessage); - } else { - SWFUpload.Console.writeLine(message); - } - } -}; - -SWFUpload.Console = {}; -SWFUpload.Console.writeLine = function (message) { - var console, documentForm; - - try { - console = document.getElementById("SWFUpload_Console"); - - if (!console) { - documentForm = document.createElement("form"); - document.getElementsByTagName("body")[0].appendChild(documentForm); - - console = document.createElement("textarea"); - console.id = "SWFUpload_Console"; - console.style.fontFamily = "monospace"; - console.setAttribute("wrap", "off"); - console.wrap = "off"; - console.style.overflow = "auto"; - console.style.width = "700px"; - console.style.height = "350px"; - console.style.margin = "5px"; - documentForm.appendChild(console); - } - - console.value += message + "\n"; - - console.scrollTop = console.scrollHeight - console.clientHeight; - } catch (ex) { - alert("Exception: " + ex.name + " Message: " + ex.message); - } -}; diff --git a/lib/swfupload/swfupload.queue.js b/lib/swfupload/swfupload.queue.js deleted file mode 100644 index 69e619da..00000000 --- a/lib/swfupload/swfupload.queue.js +++ /dev/null @@ -1,98 +0,0 @@ -/* - Queue Plug-in - - Features: - *Adds a cancelQueue() method for cancelling the entire queue. - *All queued files are uploaded when startUpload() is called. - *If false is returned from uploadComplete then the queue upload is stopped. - If false is not returned (strict comparison) then the queue upload is continued. - *Adds a QueueComplete event that is fired when all the queued files have finished uploading. - Set the event handler with the queue_complete_handler setting. - - */ - -var SWFUpload; -if (typeof(SWFUpload) === "function") { - SWFUpload.queue = {}; - - SWFUpload.prototype.initSettings = (function (oldInitSettings) { - return function () { - if (typeof(oldInitSettings) === "function") { - oldInitSettings.call(this); - } - - this.queueSettings = {}; - - this.queueSettings.queue_cancelled_flag = false; - this.queueSettings.queue_upload_count = 0; - - this.queueSettings.user_upload_complete_handler = this.settings.upload_complete_handler; - this.queueSettings.user_upload_start_handler = this.settings.upload_start_handler; - this.settings.upload_complete_handler = SWFUpload.queue.uploadCompleteHandler; - this.settings.upload_start_handler = SWFUpload.queue.uploadStartHandler; - - this.settings.queue_complete_handler = this.settings.queue_complete_handler || null; - }; - })(SWFUpload.prototype.initSettings); - - SWFUpload.prototype.startUpload = function (fileID) { - this.queueSettings.queue_cancelled_flag = false; - this.callFlash("StartUpload", [fileID]); - }; - - SWFUpload.prototype.cancelQueue = function () { - this.queueSettings.queue_cancelled_flag = true; - this.stopUpload(); - - var stats = this.getStats(); - while (stats.files_queued > 0) { - this.cancelUpload(); - stats = this.getStats(); - } - }; - - SWFUpload.queue.uploadStartHandler = function (file) { - var returnValue; - if (typeof(this.queueSettings.user_upload_start_handler) === "function") { - returnValue = this.queueSettings.user_upload_start_handler.call(this, file); - } - - // To prevent upload a real "FALSE" value must be returned, otherwise default to a real "TRUE" value. - returnValue = (returnValue === false) ? false : true; - - this.queueSettings.queue_cancelled_flag = !returnValue; - - return returnValue; - }; - - SWFUpload.queue.uploadCompleteHandler = function (file) { - var user_upload_complete_handler = this.queueSettings.user_upload_complete_handler; - var continueUpload; - - if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) { - this.queueSettings.queue_upload_count++; - } - - if (typeof(user_upload_complete_handler) === "function") { - continueUpload = (user_upload_complete_handler.call(this, file) === false) ? false : true; - } else if (file.filestatus === SWFUpload.FILE_STATUS.QUEUED) { - // If the file was stopped and re-queued don't restart the upload - continueUpload = false; - } else { - continueUpload = true; - } - - if (continueUpload) { - var stats = this.getStats(); - if (stats.files_queued > 0 && this.queueSettings.queue_cancelled_flag === false) { - this.startUpload(); - } else if (this.queueSettings.queue_cancelled_flag === false) { - this.queueEvent("queue_complete_handler", [this.queueSettings.queue_upload_count]); - this.queueSettings.queue_upload_count = 0; - } else { - this.queueSettings.queue_cancelled_flag = false; - this.queueSettings.queue_upload_count = 0; - } - } - }; -}
\ No newline at end of file diff --git a/lib/swfupload/swfupload.swf b/lib/swfupload/swfupload.swf Binary files differdeleted file mode 100644 index e3f76703..00000000 --- a/lib/swfupload/swfupload.swf +++ /dev/null diff --git a/modules/comment/helpers/comment.php b/modules/comment/helpers/comment.php index 92a286c7..7aa007cb 100644 --- a/modules/comment/helpers/comment.php +++ b/modules/comment/helpers/comment.php @@ -45,6 +45,7 @@ class comment_Core { ->error_messages("required", t("You must enter a comment")); $group->hidden("item_id")->value($item->id); module::event("comment_add_form", $form); + module::event("captcha_protect_form", $form); $group->submit("")->value(t("Add"))->class("ui-state-default ui-corner-all"); return $form; diff --git a/modules/g2_import/controllers/g2.php b/modules/g2_import/controllers/g2.php index 2c6ad1b4..d260c9b4 100644 --- a/modules/g2_import/controllers/g2.php +++ b/modules/g2_import/controllers/g2.php @@ -35,12 +35,9 @@ class G2_Controller extends Controller { $id = $input->get("g2_itemId"); if ($id) { - // Requests by id are either core.DownloadItem or - // core.ShowItem requests. - // Later versions of Gallery 2 don't specify g2_view if - // it's the default (core.ShowItem). - // And in some cases (bbcode, embedding) people are using - // the id style URLs although URL rewriting is enabled. + // Requests by id are either core.DownloadItem or core.ShowItem requests. Later versions of + // Gallery 2 don't specify g2_view if it's the default (core.ShowItem). And in some cases + // (bbcode, embedding) people are using the id style URLs although URL rewriting is enabled. $where = array(array("g2_id", "=", $id)); $view = $input->get("g2_view"); if ($view) { diff --git a/modules/g2_import/helpers/g2_import.php b/modules/g2_import/helpers/g2_import.php index f2e9dad9..c3737f8f 100644 --- a/modules/g2_import/helpers/g2_import.php +++ b/modules/g2_import/helpers/g2_import.php @@ -178,7 +178,17 @@ class g2_import_Core { "module", "rewrite", "modrewrite.embeddedLocation", $g2_embed_location)); g2($gallery->getStorage()->checkPoint()); } - self::$g2_base_url = $g2_embed_location; + + if ($g2_embed_location) { + self::$g2_base_url = $g2_embed_location; + } else { + self::$g2_base_url = $GLOBALS["gallery"]->getUrlGenerator()->generateUrl( + array(), + array("forceSessionId" => false, + "htmlEntities" => false, + "urlEncode" => false, + "useAuthToken" => false)); + } return true; } @@ -689,8 +699,7 @@ class g2_import_Core { $title = $g2_item->getTitle(); $title or $title = $g2_item->getPathComponent(); $messages[] = - t("<a href=\"%g2_url\">%title</a> from Gallery 2 could not be processed; " . - "(imported as <a href=\"%g3_url\">%title</a>)", + t("<a href=\"%g2_url\">%title</a> from Gallery 2 could not be processed; (imported as <a href=\"%g3_url\">%title</a>)", array("g2_url" => $g2_item_url, "g3_url" => $item->url(), "title" => $title)); @@ -846,6 +855,11 @@ class g2_import_Core { array("id" => $g2_comment_id, "exception" => (string)$e)); } + if (self::map($g2_comment->getId())) { + // Already imported + return; + } + $item_id = self::map($g2_comment->getParentId()); if (empty($item_id)) { // Item was not mapped. @@ -878,6 +892,8 @@ class g2_import_Core { $e); } + self::set_map($g2_comment->getId(), $comment->id, "comment"); + // Backdate the creation date. We can't do this at creation time because // Comment_Model::save() will override it. db::update("comments") diff --git a/modules/gallery/config/cookie.php b/modules/gallery/config/cookie.php index ded3bdaa..7f6ea265 100644 --- a/modules/gallery/config/cookie.php +++ b/modules/gallery/config/cookie.php @@ -37,10 +37,9 @@ $config['path'] = '/'; $config['expire'] = 0; /** - * Enable this option to only allow the cookie to be read when using the a - * secure protocol. + * Set the secure bit on the cookie if we're using HTTPS. */ -$config['secure'] = false; +$config['secure'] = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on'; /** * Enable this option to disable the cookie from being accessed when using a diff --git a/modules/gallery/config/sendmail.php b/modules/gallery/config/sendmail.php deleted file mode 100644 index 65b1d59b..00000000 --- a/modules/gallery/config/sendmail.php +++ /dev/null @@ -1,29 +0,0 @@ -<?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. - */ -/** - * PHP Mail Configuration parameters - * from => email address that appears as the from address - * line-length => word wrap length (PHP documentations suggest no larger tha 70 characters - * reply-to => what goes into the reply to header - */ -$config["from"] = "admin@gallery3.com"; -$config["line_length"] = 70; -$config["reply_to"] = "public@gallery3.com"; -$config["header_separator"] = "\n"; diff --git a/modules/gallery/controllers/admin_theme_options.php b/modules/gallery/controllers/admin_theme_options.php index 15a42ee5..57f32f96 100644 --- a/modules/gallery/controllers/admin_theme_options.php +++ b/modules/gallery/controllers/admin_theme_options.php @@ -22,14 +22,14 @@ class Admin_Theme_Options_Controller extends Admin_Controller { $view = new Admin_View("admin.html"); $view->page_title = t("Theme options"); $view->content = new View("admin_theme_options.html"); - $view->content->form = theme::get_edit_form_admin(); + $view->content->form = $this->_get_edit_form_admin(); print $view; } public function save() { access::verify_csrf(); - $form = theme::get_edit_form_admin(); + $form = $this->_get_edit_form_admin(); if ($form->validate()) { module::set_var("gallery", "page_size", $form->edit_theme->page_size->value); @@ -58,6 +58,7 @@ class Admin_Theme_Options_Controller extends Admin_Controller { module::set_var("gallery", "header_text", $form->edit_theme->header_text->value); module::set_var("gallery", "footer_text", $form->edit_theme->footer_text->value); module::set_var("gallery", "show_credits", $form->edit_theme->show_credits->value); + module::set_var("gallery", "favicon_url", $form->edit_theme->favicon_url->value); module::event("theme_edit_form_completed", $form); @@ -70,5 +71,40 @@ class Admin_Theme_Options_Controller extends Admin_Controller { print $view; } } + + private function _get_edit_form_admin() { + $form = new Forge("admin/theme_options/save/", "", null, array("id" =>"g-theme-options-form")); + $group = $form->group("edit_theme")->label(t("Theme layout")); + $group->input("page_size")->label(t("Items per page"))->id("g-page-size") + ->rules("required|valid_digit") + ->error_messages("required", t("You must enter a number")) + ->error_messages("valid_digit", t("You must enter a number")) + ->value(module::get_var("gallery", "page_size")); + $group->input("thumb_size")->label(t("Thumbnail size (in pixels)"))->id("g-thumb-size") + ->rules("required|valid_digit") + ->error_messages("required", t("You must enter a number")) + ->error_messages("valid_digit", t("You must enter a number")) + ->value(module::get_var("gallery", "thumb_size")); + $group->input("resize_size")->label(t("Resized image size (in pixels)"))->id("g-resize-size") + ->rules("required|valid_digit") + ->error_messages("required", t("You must enter a number")) + ->error_messages("valid_digit", t("You must enter a number")) + ->value(module::get_var("gallery", "resize_size")); + $group->input("favicon_url")->label(t("URL (or relative path) to your favicon.ico")) + ->id("g-favicon") + ->value(module::get_var("gallery", "favicon_url")); + $group->textarea("header_text")->label(t("Header text"))->id("g-header-text") + ->value(module::get_var("gallery", "header_text")); + $group->textarea("footer_text")->label(t("Footer text"))->id("g-footer-text") + ->value(module::get_var("gallery", "footer_text")); + $group->checkbox("show_credits")->label(t("Show site credits"))->id("g-footer-text") + ->checked(module::get_var("gallery", "show_credits")); + + module::event("theme_edit_form", $form); + + $group = $form->group("buttons"); + $group->submit("")->value(t("Save")); + return $form; + } } diff --git a/modules/gallery/controllers/albums.php b/modules/gallery/controllers/albums.php index fb7d5c59..b0887195 100644 --- a/modules/gallery/controllers/albums.php +++ b/modules/gallery/controllers/albums.php @@ -68,7 +68,7 @@ class Albums_Controller extends Items_Controller { $template->set_global("item", $album); $template->set_global("children", $album->viewable()->children($page_size, $offset)); $template->set_global("children_count", $children_count); - $template->set_global("parents", $album->parents()); + $template->set_global("parents", $album->parents()->as_array()); // view calls empty() on this $template->content = new View("album.html"); // We can't use math in ORM or the query builder, so do this by hand. It's important diff --git a/modules/gallery/controllers/move.php b/modules/gallery/controllers/move.php deleted file mode 100644 index 7b2d6165..00000000 --- a/modules/gallery/controllers/move.php +++ /dev/null @@ -1,71 +0,0 @@ -<?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 Move_Controller extends Controller { - public function browse($source_id) { - $source = ORM::factory("item", $source_id); - access::required("view", $source); - access::required("edit", $source); - - $view = new View("move_browse.html"); - $view->source = $source; - $view->tree = $this->_get_tree_html($source, ORM::factory("item", 1)); - print $view; - } - - public function save($source_id) { - access::verify_csrf(); - $source = ORM::factory("item", $source_id); - $target = ORM::factory("item", Input::instance()->post("target_id")); - - access::required("view", $source); - access::required("edit", $source); - access::required("view", $target); - access::required("edit", $target); - - item::move($source, $target); - - json::reply(array("result" => "success", "location" => $target->url())); - } - - public function show_sub_tree($source_id, $target_id) { - $source = ORM::factory("item", $source_id); - $target = ORM::factory("item", $target_id); - access::required("view", $source); - access::required("edit", $source); - access::required("view", $target); - // show targets even if they're not editable because they may contain children which *are* - // editable - - print $this->_get_tree_html($source, $target); - } - - private function _get_tree_html($source, $target) { - $view = new View("move_tree.html"); - $view->source = $source; - $view->parent = $target; - $view->children = ORM::factory("item") - ->viewable() - ->where("type", "=", "album") - ->where("parent_id", "=", $target->id) - ->find_all(); - return $view; - } - -} diff --git a/modules/gallery/controllers/movies.php b/modules/gallery/controllers/movies.php index 02d2a497..717eb8aa 100644 --- a/modules/gallery/controllers/movies.php +++ b/modules/gallery/controllers/movies.php @@ -41,7 +41,7 @@ class Movies_Controller extends Items_Controller { $template->set_global("item", $movie); $template->set_global("children", array()); $template->set_global("children_count", 0); - $template->set_global("parents", $movie->parents()); + $template->set_global("parents", $movie->parents()->as_array()); $template->set_global("next_item", $next_item); $template->set_global("previous_item", $previous_item); $template->set_global("sibling_count", $movie->parent()->viewable()->children_count($where)); diff --git a/modules/gallery/controllers/photos.php b/modules/gallery/controllers/photos.php index 8377e6c7..b22ac8e5 100644 --- a/modules/gallery/controllers/photos.php +++ b/modules/gallery/controllers/photos.php @@ -41,7 +41,7 @@ class Photos_Controller extends Items_Controller { $template->set_global("item", $photo); $template->set_global("children", array()); $template->set_global("children_count", 0); - $template->set_global("parents", $photo->parents()); + $template->set_global("parents", $photo->parents()->as_array()); $template->set_global("next_item", $next_item); $template->set_global("previous_item", $previous_item); $template->set_global("sibling_count", $photo->parent()->viewable()->children_count($where)); diff --git a/modules/gallery/controllers/uploader.php b/modules/gallery/controllers/uploader.php index 85d344d6..fb496f60 100644 --- a/modules/gallery/controllers/uploader.php +++ b/modules/gallery/controllers/uploader.php @@ -102,6 +102,14 @@ class Uploader_Controller extends Controller { } } + public function status($success_count, $error_count) { + // The "errors" won't be properly pluralized :-/ + print t2("Uploaded %count photo (%error errors)", + "Uploaded %count photos (%error errors)", + $success_count, + array("error" => $error_count)); + } + public function finish() { access::verify_csrf(); diff --git a/modules/gallery/css/gallery.css b/modules/gallery/css/gallery.css index fb72bd48..275a3d7d 100644 --- a/modules/gallery/css/gallery.css +++ b/modules/gallery/css/gallery.css @@ -78,6 +78,10 @@ margin-bottom: 0 } +#g-add-photos-status-message { + float: right; +} + /* Permissions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #g-edit-permissions-form { @@ -196,3 +200,7 @@ .rtl #g-translations ol { margin: 0 2em 1em 0; } + +.rtl #g-add-photos-status-message { + float: left; +} diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index e048118b..df5394c9 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -447,7 +447,6 @@ class gallery_event_Core { break; } $cover_title = t("Choose as the album cover"); - $move_title = t("Move to another album"); $csrf = access::csrf_token(); @@ -478,17 +477,6 @@ class gallery_event_Core { ->url(url::site("quick/rotate/$item->id/cw?csrf=$csrf&from_id={$theme_item->id}&page_type=$page_type"))); } - // @todo Don't move photos from the photo page; we don't yet have a good way of redirecting - // after move - if ($theme->page_subtype() == "album") { - $options_menu - ->append(Menu::factory("dialog") - ->id("move") - ->label($move_title) - ->css_class("ui-icon-folder-open") - ->url(url::site("move/browse/$item->id"))); - } - $parent = $item->parent(); if (access::can("edit", $parent)) { // We can't make this item the highlight if it's an album with no album cover, or if it's diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php index 569c5118..d5264fcc 100644 --- a/modules/gallery/helpers/gallery_installer.php +++ b/modules/gallery/helpers/gallery_installer.php @@ -300,7 +300,16 @@ class gallery_installer { module::set_var("gallery", "simultaneous_upload_limit", 5); module::set_var("gallery", "admin_area_timeout", 90 * 60); module::set_var("gallery", "maintenance_mode", 0); - module::set_version("gallery", 34); + module::set_var("gallery", "visible_title_length", 15); + module::set_var("gallery", "favicon_url", "lib/images/favicon.ico"); + + // Sendmail configuration + module::set_var("gallery", "email_from", "admin@example.com"); + module::set_var("gallery", "email_reply_to", "public@example.com"); + module::set_var("gallery", "email_line_length", 70); + module::set_var("gallery", "email_header_separator", serialize("\n")); + + module::set_version("gallery", 37); } static function upgrade($version) { @@ -584,6 +593,24 @@ class gallery_installer { $db->query("ALTER TABLE {access_caches} ADD KEY (`item_id`)"); module::set_version("gallery", $version = 34); } + + if ($version == 34) { + module::set_var("gallery", "visible_title_length", 15); + module::set_version("gallery", $version = 35); + } + + if ($version == 35) { + module::set_var("gallery", "favicon_url", "lib/images/favicon.ico"); + module::set_version("gallery", $version = 36); + } + + if ($version == 36) { + module::set_var("gallery", "email_from", "admin@example.com"); + module::set_var("gallery", "email_reply_to", "public@example.com"); + module::set_var("gallery", "email_line_length", 70); + module::set_var("gallery", "email_header_separator", serialize("\n")); + module::set_version("gallery", $version = 37); + } } static function uninstall() { diff --git a/modules/gallery/helpers/gallery_task.php b/modules/gallery/helpers/gallery_task.php index 6a1fc28a..0886aad0 100644 --- a/modules/gallery/helpers/gallery_task.php +++ b/modules/gallery/helpers/gallery_task.php @@ -58,8 +58,7 @@ class gallery_task_Core { $tasks[] = Task_Definition::factory() ->callback("gallery_task::fix") ->name(t("Fix your Gallery")) - ->description(t("Fix a variety of problems that might cause your Gallery to act " . - "strangely. Requires maintenance mode.")) + ->description(t("Fix a variety of problems that might cause your Gallery to act strangely. Requires maintenance mode.")) ->severity(log::SUCCESS); return $tasks; diff --git a/modules/gallery/helpers/graphics.php b/modules/gallery/helpers/graphics.php index cc4d2e76..bb085ea5 100644 --- a/modules/gallery/helpers/graphics.php +++ b/modules/gallery/helpers/graphics.php @@ -338,8 +338,7 @@ class graphics_Core { } else { $toolkits->imagemagick->installed = false; $toolkits->imagemagick->error = - t("ImageMagick is installed, but PHP's open_basedir restriction " . - "prevents Gallery from using it."); + t("ImageMagick is installed, but PHP's open_basedir restriction prevents Gallery from using it."); } } else { $toolkits->imagemagick->installed = false; @@ -363,8 +362,7 @@ class graphics_Core { } else { $toolkits->graphicsmagick->installed = false; $toolkits->graphicsmagick->error = - t("GraphicsMagick is installed, but PHP's open_basedir restriction " . - "prevents Gallery from using it."); + t("GraphicsMagick is installed, but PHP's open_basedir restriction prevents Gallery from using it."); } } else { $toolkits->graphicsmagick->installed = false; diff --git a/modules/gallery/helpers/l10n_scanner.php b/modules/gallery/helpers/l10n_scanner.php index 2287a7ba..843c74f7 100644 --- a/modules/gallery/helpers/l10n_scanner.php +++ b/modules/gallery/helpers/l10n_scanner.php @@ -74,10 +74,21 @@ class l10n_scanner_Core { unset($raw_tokens); if (!empty($func_token_list["t"])) { - l10n_scanner::_parse_t_calls($tokens, $func_token_list["t"], $cache); + $errors = l10n_scanner::_parse_t_calls($tokens, $func_token_list["t"], $cache); + foreach ($errors as $line => $error) { + Kohana_Log::add( + "error", "Translation scanner error. " . + "file: " . substr($file, strlen(DOCROOT)) . ", line: $line, context: $error"); + } } + if (!empty($func_token_list["t2"])) { - l10n_scanner::_parse_plural_calls($tokens, $func_token_list["t2"], $cache); + $errors = l10n_scanner::_parse_plural_calls($tokens, $func_token_list["t2"], $cache); + foreach ($errors as $line => $error) { + Kohana_Log::add( + "error", "Translation scanner error. " . + "file: " . substr($file, strlen(DOCROOT)) . ", line: $line, context: $error"); + } } } @@ -91,6 +102,7 @@ class l10n_scanner_Core { } private static function _parse_t_calls(&$tokens, &$call_list, &$cache) { + $errors = array(); foreach ($call_list as $index) { $function_name = $tokens[$index++]; $parens = $tokens[$index++]; @@ -103,14 +115,21 @@ class l10n_scanner_Core { $message = self::_escape_quoted_string($first_param[1]); l10n_scanner::process_message($message, $cache); } else { - // t() found, but inside is something which is not a string literal. - // @todo Call status callback with error filename/line. + if (is_array($first_param) && ($first_param[0] == T_CONSTANT_ENCAPSED_STRING)) { + // Malformed string literals; escalate this + $errors[$first_param[2]] = + var_export(array($function_name, $parens, $first_param, $next_token), 1); + } else { + // t() found, but inside is something which is not a string literal. That's fine. + } } } } + return $errors; } private static function _parse_plural_calls(&$tokens, &$call_list, &$cache) { + $errors = array(); foreach ($call_list as $index) { $function_name = $tokens[$index++]; $parens = $tokens[$index++]; @@ -127,11 +146,17 @@ class l10n_scanner_Core { $plural = self::_escape_quoted_string($second_param[1]); l10n_scanner::process_message(array("one" => $singular, "other" => $plural), $cache); } else { - // t2() found, but inside is something which is not a string literal. - // @todo Call status callback with error filename/line. + if (is_array($first_param) && $first_param[0] == T_CONSTANT_ENCAPSED_STRING) { + $errors[$first_param[2]] = var_export( + array($function_name, $parens, $first_param, + $first_separator, $second_param, $next_token), 1); + } else { + // t2() found, but inside is something which is not a string literal. That's fine. + } } } } + return $errors; } /** diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php index 4ff29a7b..3e55eefe 100644 --- a/modules/gallery/helpers/movie.php +++ b/modules/gallery/helpers/movie.php @@ -84,7 +84,7 @@ class movie_Core { } static function find_ffmpeg() { - if (!$ffmpeg_path = module::get_var("gallery", "ffmpeg_path")) { + if (!($ffmpeg_path = module::get_var("gallery", "ffmpeg_path")) || !file_exists($ffmpeg_path)) { $graphics_path = module::get_var("gallery", "graphics_toolkit_path", null); putenv("PATH=" . getenv("PATH") . (empty($graphics_path) ? "" : ":$graphics_path") . diff --git a/modules/gallery/helpers/theme.php b/modules/gallery/helpers/theme.php index 9df3eaf2..1dc1f3b6 100644 --- a/modules/gallery/helpers/theme.php +++ b/modules/gallery/helpers/theme.php @@ -77,39 +77,6 @@ class theme_Core { $config->set("core.modules", $modules); } - static function get_edit_form_admin() { - $form = new Forge("admin/theme_options/save/", "", null, array("id" =>"g-theme-options-form")); - $group = $form->group("edit_theme")->label(t("Theme layout")); - $group->input("page_size")->label(t("Items per page"))->id("g-page-size") - ->rules("required|valid_digit") - ->error_messages("required", t("You must enter a number")) - ->error_messages("valid_digit", t("You must enter a number")) - ->value(module::get_var("gallery", "page_size")); - $group->input("thumb_size")->label(t("Thumbnail size (in pixels)"))->id("g-thumb-size") - ->rules("required|valid_digit") - ->error_messages("required", t("You must enter a number")) - ->error_messages("valid_digit", t("You must enter a number")) - ->value(module::get_var("gallery", "thumb_size")); - $group->input("resize_size")->label(t("Resized image size (in pixels)"))->id("g-resize-size") - ->rules("required|valid_digit") - ->error_messages("required", t("You must enter a number")) - ->error_messages("valid_digit", t("You must enter a number")) - ->value(module::get_var("gallery", "resize_size")); - $group->textarea("header_text")->label(t("Header text"))->id("g-header-text") - ->value(module::get_var("gallery", "header_text")); - $group->textarea("footer_text")->label(t("Footer text"))->id("g-footer-text") - ->value(module::get_var("gallery", "footer_text")); - $group->checkbox("show_credits")->label(t("Show site credits"))->id("g-footer-text") - ->checked(module::get_var("gallery", "show_credits")); - - module::event("theme_edit_form", $form); - - $group = $form->group("buttons") - ->set_attr("style","border: none"); - $group->submit("")->value(t("Save")); - return $form; - } - static function get_info($theme_name) { $theme_name = preg_replace("/[^a-zA-Z0-9\._-]/", "", $theme_name); $file = THEMEPATH . "$theme_name/theme.info"; diff --git a/modules/gallery/helpers/user_profile.php b/modules/gallery/helpers/user_profile.php index e5ebce84..d9cc8ace 100644 --- a/modules/gallery/helpers/user_profile.php +++ b/modules/gallery/helpers/user_profile.php @@ -35,19 +35,20 @@ class user_profile_Core { $group->input("reply_to") ->label(t("From:")) ->rules("required|length[1, 256]|valid_email") - ->error_messages("required", t("Field is required")) - ->error_messages("max_length", t("Field exceeds 256 bytes")) - ->error_messages("valid_email", t("Field is not a valid email address")); + ->error_messages("required", t("You must enter a valid email address")) + ->error_messages("max_length", t("Your email address is too long")) + ->error_messages("valid_email", t("You must enter a valid email address")); $group->input("subject") ->label(t("Subject:")) ->rules("required|length[1, 256]") - ->error_messages("required", t("Field is required")) - ->error_messages("max_length", t("Field exceeds 256 bytes")); + ->error_messages("required", t("Your message must have a subject")) + ->error_messages("max_length", t("Your subject is too long")); $group->textarea("message") ->label(t("Message:")) ->rules("required") - ->error_messages("required", t("Field is required")); + ->error_messages("required", t("You must enter a message")); module::event("user_profile_contact_form", $form); + module::event("captcha_protect_form", $form); $group->submit("")->value(t("Send")); return $form; } diff --git a/modules/gallery/libraries/Form_Uploadify.php b/modules/gallery/libraries/Form_Uploadify.php index e5b6d819..79477763 100644 --- a/modules/gallery/libraries/Form_Uploadify.php +++ b/modules/gallery/libraries/Form_Uploadify.php @@ -46,6 +46,8 @@ class Form_Uploadify_Core extends Form_Input { $v->album = $this->data["album"]; $v->script_data = $this->data["script_data"]; $v->simultaneous_upload_limit = module::get_var("gallery", "simultaneous_upload_limit"); + $v->movies_allowed = (bool) movie::find_ffmpeg(); + $v->suhosin_session_encrypt = (bool) ini_get("suhosin.session.encrypt"); return $v; } diff --git a/modules/gallery/libraries/IdentityProvider.php b/modules/gallery/libraries/IdentityProvider.php index 5f341c90..4ef07e1a 100644 --- a/modules/gallery/libraries/IdentityProvider.php +++ b/modules/gallery/libraries/IdentityProvider.php @@ -61,8 +61,7 @@ class IdentityProvider_Core { * Return a commen confirmation message */ static function confirmation_message() { - return t("Are you sure you want to change your Identity Provider? " . - "Continuing will delete all existing users."); + return t("Are you sure you want to change your Identity Provider? Continuing will delete all existing users."); } static function change_provider($new_provider) { @@ -113,8 +112,7 @@ class IdentityProvider_Core { } message::error( - t("Error attempting to enable \"%new_provider\" identity provider, " . - "reverted to \"%old_provider\" identity provider", + t("Error attempting to enable \"%new_provider\" identity provider, reverted to \"%old_provider\" identity provider", array("new_provider" => $new_provider, "old_provider" => $current_provider))); $restore_already_running = false; diff --git a/modules/gallery/libraries/Sendmail.php b/modules/gallery/libraries/Sendmail.php index ded7b2ef..0fa554b4 100644 --- a/modules/gallery/libraries/Sendmail.php +++ b/modules/gallery/libraries/Sendmail.php @@ -35,10 +35,12 @@ class Sendmail_Core { public function __construct() { $this->headers = array(); - $config = Kohana::config("sendmail"); - foreach ($config as $key => $value) { - $this->$key($value); - } + $domain = Input::instance()->server("HTTP_HOST"); + $this->from(module::get_var("gallery", "email_from", "admin@$domain")); + $this->reply_to(module::get_var("gallery", "email_reply_to", "public@$domain")); + $this->line_length(module::get_var("gallery", "email_line_length", 70)); + $separator = module::get_var("gallery", "email_header_separator", null); + $this->header_separator(empty($separator) ? "\n" : deserialize($separator)); } public function __get($key) { diff --git a/modules/gallery/libraries/Theme_View.php b/modules/gallery/libraries/Theme_View.php index 46291005..7a6bc1da 100644 --- a/modules/gallery/libraries/Theme_View.php +++ b/modules/gallery/libraries/Theme_View.php @@ -236,6 +236,13 @@ class Theme_View_Core extends Gallery_View { case "thumb_bottom": case "thumb_info": case "thumb_top": + if ($function == "head") { + // Stash any CSS we have already; that came from the theme and we want theme CSS to + // override module CSs + $save_css = $this->css; + $this->css = array(); + } + $blocks = array(); if (method_exists("gallery_theme", $function)) { switch (count($args)) { @@ -275,6 +282,8 @@ class Theme_View_Core extends Gallery_View { } if ($function == "head") { + // Merge the theme CSS/JS at the end + $this->css = array_merge($this->css, $save_css); array_unshift($blocks, $this->combine_files($this->css, "css")); array_unshift($blocks, $this->combine_files($this->scripts, "javascript")); } diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php index c4591279..1db766e9 100644 --- a/modules/gallery/models/item.php +++ b/modules/gallery/models/item.php @@ -411,7 +411,9 @@ class Item_Model extends ORM_MPTT { } // This will almost definitely trigger another save, so put it at the end so that we're - // tail recursive. + // tail recursive. Null out the data file variable first, otherwise the next save will + // trigger an item_updated_data_file event. + $this->data_file = null; module::event("item_created", $this); } else { // Update an existing item diff --git a/modules/gallery/module.info b/modules/gallery/module.info index 084a0945..901158b5 100644 --- a/modules/gallery/module.info +++ b/modules/gallery/module.info @@ -1,3 +1,3 @@ name = "Gallery 3" description = "Gallery core application" -version = 34 +version = 37 diff --git a/modules/gallery/tests/Gallery_Filters.php b/modules/gallery/tests/Gallery_Filters.php index 052990d5..1c07f93e 100644 --- a/modules/gallery/tests/Gallery_Filters.php +++ b/modules/gallery/tests/Gallery_Filters.php @@ -43,7 +43,6 @@ class GalleryCodeFilterIterator extends FilterIterator { strpos($path_name, MODPATH . "unit_test") !== false || strpos($path_name, MODPATH . "exif/lib") !== false || strpos($path_name, MODPATH . "user/lib/PasswordHash") !== false || - strpos($path_name, DOCROOT . "lib/swfupload") !== false || strpos($path_name, SYSPATH) !== false || strpos($path_name, MODPATH . "gallery/libraries/HTMLPurifier") !== false || substr($path_name, -1, 1) == "~"); diff --git a/modules/gallery/tests/Sendmail_Test.php b/modules/gallery/tests/Sendmail_Test.php index b9406047..92974e5c 100644 --- a/modules/gallery/tests/Sendmail_Test.php +++ b/modules/gallery/tests/Sendmail_Test.php @@ -23,9 +23,10 @@ class Sendmail_Test extends Gallery_Unit_Test_Case { } public function sendmail_test() { + $domain = Input::instance()->server("HTTP_HOST"); $expected = "To: receiver@someemail.com\r\n" . "From: from@gallery3.com\n" . - "Reply-To: public@gallery3.com\r\n" . + "Reply-To: public@$domain\r\n" . "Subject: Test Email Unit test\r\n\r\n" . "The mail message body"; $result = Sendmail_For_Test::factory() @@ -45,8 +46,9 @@ class Sendmail_Test extends Gallery_Unit_Test_Case { } public function sendmail_reply_to_test() { + $domain = Input::instance()->server("HTTP_HOST"); $expected = "To: receiver@someemail.com\r\n" . - "From: from@gallery3.com\n" . + "From: admin@$domain\n" . "Reply-To: reply-to@gallery3.com\r\n" . "Subject: Test Email Unit test\r\n\r\n" . "The mail message body"; @@ -61,9 +63,10 @@ class Sendmail_Test extends Gallery_Unit_Test_Case { } public function sendmail_html_message_test() { + $domain = Input::instance()->server("HTTP_HOST"); $expected = "To: receiver@someemail.com\r\n" . - "From: from@gallery3.com\n" . - "Reply-To: public@gallery3.com\n" . + "From: admin@$domain\n" . + "Reply-To: public@$domain\n" . "MIME-Version: 1.0\n" . "Content-Type: text/html; charset=UTF-8\r\n" . "Subject: Test Email Unit test\r\n\r\n" . @@ -80,9 +83,10 @@ class Sendmail_Test extends Gallery_Unit_Test_Case { } public function sendmail_wrapped_message_test() { + $domain = Input::instance()->server("HTTP_HOST"); $expected = "To: receiver@someemail.com\r\n" . - "From: from@gallery3.com\n" . - "Reply-To: public@gallery3.com\r\n" . + "From: admin@$domain\n" . + "Reply-To: public@$domain\r\n" . "Subject: Test Email Unit test\r\n\r\n" . "This is a long message that needs to go\n" . "over forty characters If we get lucky we\n" . diff --git a/modules/gallery/views/admin_theme_options.html.php b/modules/gallery/views/admin_theme_options.html.php index b4a90682..e452913e 100644 --- a/modules/gallery/views/admin_theme_options.html.php +++ b/modules/gallery/views/admin_theme_options.html.php @@ -1,35 +1,4 @@ <?php defined("SYSPATH") or die("No direct script access.") ?> -<script type="text/javascript"> - $("#g-theme-options-form").ready(function() { - var contents = $("#g-theme-options-form fieldset:not(:last-child)"); - if (contents.length > 1) { - $("<div id='g-theme-options-form-tabs'>" + - " <ul class='tabnav'></ul>" + - "</div>").insertBefore("#g-theme-options-form fieldset:last-child"); - $(contents).each(function(index) { - var text = $("legend", this).text(); - var tabId = "tab_" + index; - var tabContentId = "tab_content_" + index; - if (text == "") { - text = <?= t("Tab_")->for_js() ?> + index; - } - $(".tabnav").append( - "<li><a id='" + tabId + "' href='#" + tabContentId + "'>" + text + "</a></li>"); - $("#g-theme-options-form-tabs").append( - "<div id='" + tabContentId + "' class='tabdiv'></div>"); - if ($("li.g-error", this).length > 0) { - $("#" + tabId).addClass("g-error"); - } - $("#" + tabContentId).append($("ul", this)); - $(this).remove(); - }); - $("#g-theme-options-form-tabs").tabs({}); - } else { - $("#g-theme-options-form fieldset:first legend").hide(); - } - }); -</script> - <div class="g-block"> <h1> <?= t("Theme options") ?> </h1> <div class="g-block-content"> diff --git a/modules/gallery/views/form_uploadify.html.php b/modules/gallery/views/form_uploadify.html.php index 4f564b07..36f5f284 100644 --- a/modules/gallery/views/form_uploadify.html.php +++ b/modules/gallery/views/form_uploadify.html.php @@ -2,109 +2,162 @@ <script type="text/javascript" src="<?= url::file("lib/swfobject.js") ?>"></script> <script type="text/javascript" src="<?= url::file("lib/uploadify/jquery.uploadify.min.js") ?>"></script> <script type="text/javascript"> + <? $flash_minimum_version = "9.0.24" ?> + var success_count = 0; + var error_count = 0; + var updating = 0; $("#g-add-photos-canvas").ready(function () { - $("#g-uploadify").uploadify({ - width: 150, - height: 33, - uploader: "<?= url::file("lib/uploadify/uploadify.swf") ?>", - script: "<?= url::site("uploader/add_photo/{$album->id}") ?>", - scriptData: <?= json_encode($script_data) ?>, - fileExt: "*.gif;*.jpg;*.jpeg;*.png;*.flv;*.mp4;*.m4v;*.GIF;*.JPG;*.JPEG;*.PNG;*.FLV;*.MP4;*.M4V", - fileDesc: <?= t("Photos and movies")->for_js() ?>, - cancelImg: "<?= url::file("lib/uploadify/cancel.png") ?>", - simUploadLimit: <?= $simultaneous_upload_limit ?>, - wmode: "transparent", - hideButton: true, /* should be true */ - auto: true, - multi: true, - onAllComplete: function(filesUploaded, errors, allbytesLoaded, speed) { - $("#g-upload-cancel-all") - .addClass("ui-state-disabled") - .attr("disabled", "disabled"); - return true; - }, - onClearQueue: function(event) { - $("#g-upload-cancel-all") - .addClass("ui-state-disabled") - .attr("disabled", "disabled"); - return true; - }, - onComplete: function(event, queueID, fileObj, response, data) { - var re = /^error: (.*)$/i; - var msg = re.exec(response); - if (msg) { - $("#g-add-photos-status ul").append( - "<li class=\"g-error\">" + fileObj.name + " - " + msg[1] + "</li>"); - } else { - $("#g-add-photos-status ul").append( - "<li class=\"g-success\">" + fileObj.name + " - " + <?= t("Completed")->for_js() ?> + "</li>"); - } - return true; - }, - onError: function(event, queueID, fileObj, errorObj) { - var msg = " - "; - if (errorObj.type == "HTTP") { - if (errorObj.info == "500") { - msg += <?= t("Unable to process this file")->for_js() ?>; - // Server error - check server logs - } else if (errorObj.info == "404") { - msg += <?= t("The upload script was not found.")->for_js() ?>; - // Server script not found - } else { - // Server Error: status: errorObj.info - msg += (<?= t("Server error: __INFO__")->for_js() ?>.replace("__INFO__", errorObj.info)); - } - } else if (errorObj.type == "File Size") { - var sizelimit = $("#g-uploadify").uploadifySettings(sizeLimit); - msg += fileObj.name+' '+errorObj.type+' Limit: '+Math.round(d.sizeLimit/1024)+'KB'; - } else { - msg += (<?= t("Server error: __INFO__ (__TYPE__)")->for_js() ?> - .replace("__INFO__", errorObj.info) - .replace("__TYPE__", errorObj.type)); - } - $("#g-add-photos-status ul").append( - "<li class=\"g-error\">" + fileObj.name + msg + "</li>"); - $("#g-uploadify" + queueID).remove(); - }, - onSelect: function(event) { - if ($("#g-upload-cancel-all").hasClass("ui-state-disabled")) { + var update_status = function() { + if (updating) { + // poor man's mutex + setTimeout(function() { update_status(); }, 500); + } + updating = 1; + $.get("<?= url::site("uploader/status/_S/_E") ?>" + .replace("_S", success_count).replace("_E", error_count), + function(data) { + $("#g-add-photos-status-message").html(data); + updating = 0; + }); + }; + + if (swfobject.hasFlashPlayerVersion("<?= $flash_minimum_version ?>")) { + $("#g-uploadify").uploadify({ + width: 150, + height: 33, + uploader: "<?= url::file("lib/uploadify/uploadify.swf") ?>", + script: "<?= url::site("uploader/add_photo/{$album->id}") ?>", + scriptData: <?= json_encode($script_data) ?>, + fileExt: "*.gif;*.jpg;*.jpeg;*.png;*.GIF;*.JPG;*.JPEG;*.PNG<? if ($movies_allowed): ?>;*.flv;*.mp4;*.m4v;*.FLV;*.MP4;*.M4V<? endif ?>", + fileDesc: <?= t("Photos and movies")->for_js() ?>, + cancelImg: "<?= url::file("lib/uploadify/cancel.png") ?>", + simUploadLimit: <?= $simultaneous_upload_limit ?>, + wmode: "transparent", + hideButton: true, /* should be true */ + auto: true, + multi: true, + onAllComplete: function(filesUploaded, errors, allbytesLoaded, speed) { + $("#g-upload-cancel-all") + .addClass("ui-state-disabled") + .attr("disabled", "disabled"); + $("#g-upload-done") + .removeClass("ui-state-disabled") + .attr("disabled", null); + return true; + }, + onClearQueue: function(event) { $("#g-upload-cancel-all") + .addClass("ui-state-disabled") + .attr("disabled", "disabled"); + $("#g-upload-done") .removeClass("ui-state-disabled") .attr("disabled", null); + return true; + }, + onComplete: function(event, queueID, fileObj, response, data) { + var re = /^error: (.*)$/i; + var msg = re.exec(response); + $("#g-add-photos-status ul").append( + "<li id=\"q" + queueID + "\" class=\"g-success\">" + fileObj.name + " - " + + <?= t("Completed")->for_js() ?> + "</li>"); + setTimeout(function() { $("#q" + queueID).slideUp("slow") }, 5000); + success_count++; + update_status(); + return true; + }, + onError: function(event, queueID, fileObj, errorObj) { + var msg = " - "; + if (errorObj.type == "HTTP") { + if (errorObj.info == "500") { + msg += <?= t("Unable to process this file")->for_js() ?>; + // Server error - check server logs + } else if (errorObj.info == "404") { + msg += <?= t("The upload script was not found.")->for_js() ?>; + // Server script not found + } else { + // Server Error: status: errorObj.info + msg += (<?= t("Server error: __INFO__")->for_js() ?>.replace("__INFO__", errorObj.info)); + } + } else if (errorObj.type == "File Size") { + var sizelimit = $("#g-uploadify").uploadifySettings(sizeLimit); + msg += fileObj.name+' '+errorObj.type+' Limit: '+Math.round(d.sizeLimit/1024)+'KB'; + } else { + msg += (<?= t("Server error: __INFO__ (__TYPE__)")->for_js() ?> + .replace("__INFO__", errorObj.info) + .replace("__TYPE__", errorObj.type)); + } + $("#g-add-photos-status ul").append( + "<li class=\"g-error\">" + fileObj.name + msg + "</li>"); + $("#g-uploadify" + queueID).remove(); + error_count++; + update_status(); + }, + onSelect: function(event) { + if ($("#g-upload-cancel-all").hasClass("ui-state-disabled")) { + $("#g-upload-cancel-all") + .removeClass("ui-state-disabled") + .attr("disabled", null); + $("#g-upload-done") + .addClass("ui-state-disabled") + .attr("disabled", "disabled"); + } + return true; } - return true; - } - }); + }); + } else { + $(".requires-flash").hide(); + $(".no-flash").show(); + } }); </script> -<? if (ini_get("suhosin.session.encrypt")): ?> -<ul id="g-action-status" class="g-message-block"> - <li class="g-error"> - <?= t("Error: your server is configured to use the <a href=\"%encrypt_url\"><code>suhosin.session.encrypt</code></a> setting from <a href=\"%suhosin_url\">Suhosin</a>. You must disable this setting to upload photos.", - array("encrypt_url" => "http://www.hardened-php.net/suhosin/configuration.html#suhosin.session.encrypt", - "suhosin_url" => "http://www.hardened-php.net/suhosin/")) ?> - </li> -</ul> -<? endif ?> +<div class="requires-flash"> + <? if ($suhosin_session_encrypt || !$movies_allowed): ?> + <div class="g-message-block g-info"> + <? if ($suhosin_session_encrypt): ?> + <p class="g-error"> + <?= t("Error: your server is configured to use the <a href=\"%encrypt_url\"><code>suhosin.session.encrypt</code></a> setting from <a href=\"%suhosin_url\">Suhosin</a>. You must disable this setting to upload photos.", + array("encrypt_url" => "http://www.hardened-php.net/suhosin/configuration.html#suhosin.session.encrypt", + "suhosin_url" => "http://www.hardened-php.net/suhosin/")) ?> + </p> + <? endif ?> -<div> - <p> - <?= t("Photos will be uploaded to album: ") ?> - </p> - <ul class="g-breadcrumbs ui-helper-clearfix"> - <? foreach ($album->parents() as $i => $parent): ?> - <li<? if ($i == 0) print " class=\"g-first\"" ?>> <?= html::clean($parent->title) ?> </li> - <? endforeach ?> - <li class="g-active"> <?= html::purify($album->title) ?> </li> - </ul> -</div> + <? if (!$movies_allowed): ?> + <p class="g-warning"> + <?= t("Can't find <i>ffmpeg</i> on your system. Movie uploading disabled. <a href=\"%help_url\">Help!</a>", array("help_url" => "http://codex.gallery2.org/Gallery3:FAQ#Why_does_it_say_I.27m_missing_ffmpeg.3F")) ?> + </p> + <? endif ?> + </div> + <? endif ?> + + <div> + <p> + <?= t("Photos will be uploaded to album: ") ?> + </p> + <ul class="g-breadcrumbs ui-helper-clearfix"> + <? foreach ($album->parents() as $i => $parent): ?> + <li<? if ($i == 0) print " class=\"g-first\"" ?>> <?= html::clean($parent->title) ?> </li> + <? endforeach ?> + <li class="g-active"> <?= html::purify($album->title) ?> </li> + </ul> + </div> -<div id="g-add-photos-canvas"> - <button id="g-add-photos-button" class="g-button ui-state-default ui-corner-all" href="#"><?= t("Select photos...") ?></button> - <span id="g-uploadify"></span> + <div id="g-add-photos-canvas"> + <button id="g-add-photos-button" class="g-button ui-state-default ui-corner-all" href="#"><?= t("Select photos...") ?></button> + <span id="g-uploadify"></span> + </div> + <div id="g-add-photos-status"> + <ul id="g-action-status" class="g-message-block"> + </ul> + </div> </div> -<div id="g-add-photos-status"> - <ul id="g-action-status" class="g-message-block"> - </ul> + +<div class="no-flash" style="display: none"> + <p> + <?= t("Your browser must have Adobe Flash Player version %flash_minimum_version or greater installed to use this feature.", array("flash_minimum_version" => $flash_minimum_version)) ?> + </p> + <a href="http://www.adobe.com/go/getflashplayer"> + <img src="<?= request::protocol() ?>://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" + alt=<?= t("Get Adobe Flash Player")->for_js() ?> /> + </a> </div> diff --git a/modules/gallery/views/form_uploadify_buttons.html.php b/modules/gallery/views/form_uploadify_buttons.html.php index d88bb6aa..e002d82d 100644 --- a/modules/gallery/views/form_uploadify_buttons.html.php +++ b/modules/gallery/views/form_uploadify_buttons.html.php @@ -1,8 +1,11 @@ <?php defined("SYSPATH") or die("No direct script access.") ?> -<!-- Proxy the done request back to our form, since its been ajaxified --> -<button id="g-upload-done" class="ui-state-default ui-corner-all" onclick="$('#g-add-photos-form').submit();return false;"> +<div class="requires-flash"> + <!-- Proxy the done request back to our form, since its been ajaxified --> + <button id="g-upload-done" class="ui-state-default ui-corner-all" onclick="$('#g-add-photos-form').submit();return false;"> <?= t("Done") ?> -</button> -<button id="g-upload-cancel-all" class="ui-state-default ui-corner-all ui-state-disabled" onclick="$('#g-uploadify').uploadifyClearQueue();return false;" disabled="disabled"> - <?= t("Cancel All") ?> -</button> + </button> + <button id="g-upload-cancel-all" class="ui-state-default ui-corner-all ui-state-disabled" onclick="$('#g-uploadify').uploadifyClearQueue();return false;" disabled="disabled"> + <?= t("Cancel uploads") ?> + </button> + <span id="g-add-photos-status-message" /> +</div> diff --git a/modules/gallery/views/move_browse.html.php b/modules/gallery/views/move_browse.html.php deleted file mode 100644 index f77c724c..00000000 --- a/modules/gallery/views/move_browse.html.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php defined("SYSPATH") or die("No direct script access.") ?> -<div> -<script type="text/javascript"> - var load_tree = function(target_id, locked) { - var load_url = "<?= url::site("move/show_sub_tree/{$source->id}/__TARGETID__") ?>"; - var node = $("#node_" + target_id); - $("#g-move .node a").removeClass("selected"); - node.find("a:first").addClass("selected"); - if (locked) { - $("#g-move-button").attr("disabled", "disabled"); - $("#g-move form input[name=target_id]").attr("value", ""); - } else { - $("#g-move-button").removeAttr("disabled"); - $("#g-move form input[name=target_id]").attr("value", target_id); - } - var sub_tree = $("#tree_" + target_id); - if (sub_tree.length) { - sub_tree.toggle(); - } else { - $.get(load_url.replace("__TARGETID__", target_id), {}, - function(data) { - node.html(data); - node.find("a:first").addClass("selected"); - }); - } - } -</script> -<h1 style="display:none" > - <? if ($source->type == "photo"): ?> - <?= t("Move this photo to a new album") ?> - <? elseif ($source->type == "movie"): ?> - <?= t("Move this movie to a new album") ?> - <? elseif ($source->type == "album"): ?> - <?= t("Move this album to a new album") ?> - <? endif ?> -</h1> -<div id="g-move"> - <ul id="tree_0"> - <li id="node_1" class="node"> - <?= $tree ?> - </li> - </ul> - <form method="post" action="<?= url::site("move/save/$source->id") ?>"> - <?= access::csrf_form_field() ?> - <input type="hidden" name="target_id" value="" /> - <input type="submit" id="g-move-button" value="<?= t("Move")->for_html_attr() ?>" - disabled="disabled" class="submit" /> - </form> -</div> -</div> diff --git a/modules/gallery/views/move_tree.html.php b/modules/gallery/views/move_tree.html.php deleted file mode 100644 index e629e1bb..00000000 --- a/modules/gallery/views/move_tree.html.php +++ /dev/null @@ -1,19 +0,0 @@ -<?php defined("SYSPATH") or die("No direct script access.") ?> -<?= $parent->thumb_img(array(), 25); ?> -<? if (!access::can("edit", $parent) || $source->contains($parent)): ?> -<a href="javascript:load_tree('<?= $parent->id ?>',1)"> <?= html::clean($parent->title) ?> <?= t("(locked)") ?> </a> -<? else: ?> -<a href="javascript:load_tree('<?= $parent->id ?>',0)"> <?= html::clean($parent->title) ?></a> -<? endif ?> -<ul id="tree_<?= $parent->id ?>"> - <? foreach ($children as $child): ?> - <li id="node_<?= $child->id ?>" class="node"> - <?= $child->thumb_img(array(), 25); ?> - <? if (!access::can("edit", $child) || $source->contains($child)): ?> - <a href="javascript:load_tree('<?= $child->id ?>',1)"> <?= html::clean($child->title) ?> <?= t("(locked)") ?></a> - <? else: ?> - <a href="javascript:load_tree('<?= $child->id ?>',0)"> <?= html::clean($child->title) ?> </a> - <? endif ?> - </li> - <? endforeach ?> -</ul> diff --git a/modules/notification/helpers/notification_event.php b/modules/notification/helpers/notification_event.php index df9dbe48..5cd10de8 100644 --- a/modules/notification/helpers/notification_event.php +++ b/modules/notification/helpers/notification_event.php @@ -21,15 +21,6 @@ class notification_event_Core { // The assumption is that the exception was logged at a lower level, but we // don't want to screw up the processing that was generating the notification // so we don't pass the exception up the call stack - static function item_updated($original, $new) { - try { - notification::send_item_updated($original, $new); - } catch (Exception $e) { - Kohana_Log::add("error", "@todo notification_event::item_updated() failed"); - Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString()); - } - } - static function item_created($item) { try { notification::send_item_add($item); diff --git a/modules/organize/controllers/organize.php b/modules/organize/controllers/organize.php index 7b2ba8ef..2b6e4186 100644 --- a/modules/organize/controllers/organize.php +++ b/modules/organize/controllers/organize.php @@ -31,10 +31,9 @@ class Organize_Controller extends Controller { $sort_fields[$field] = (string)$description; } $sort_order = array("ASC" => (string)t("Ascending"), "DESC" => (string)t("Descending")); - $file_filter = json_encode( - array("photo" => array("label" => "Images", - "types" => array("*.jpg", "*.jpeg", "*.png", "*.gif")), - "movie" => array("label" => "Movies", "types" => array("*.flv", "*.mp4", "*.m4v")))); + $file_filter = json_encode(array( + "photo" => array("label" => "Images", "types" => array("*.jpg", "*.jpeg", "*.png", "*.gif")), + "movie" => array("label" => "Movies", "types" => array("*.flv", "*.mp4", "*.m4v")))); $v = new View("organize_dialog.html"); $v->album = $album; @@ -43,6 +42,7 @@ class Organize_Controller extends Controller { $v->file_filter = addslashes($file_filter); $v->sort_order = addslashes(json_encode($sort_order)); $v->sort_fields = addslashes(json_encode($sort_fields)); + $v->selected_id = Input::instance()->get("selected_id", null); $v->rest_uri = url::site("rest") . "/"; $v->controller_uri = url::site("organize") . "/"; $v->swf_uri = url::file("modules/organize/lib/Gallery3WebClient.swf?") . diff --git a/modules/organize/helpers/organize_event.php b/modules/organize/helpers/organize_event.php index ae05fb5d..2f997600 100644 --- a/modules/organize/helpers/organize_event.php +++ b/modules/organize/helpers/organize_event.php @@ -32,13 +32,23 @@ class organize_event_Core { } static function context_menu($menu, $theme, $item) { - if ($item->is_album() && access::can("edit", $item)) { - $menu->get("options_menu") - ->append(Menu::factory("dialog") - ->id("organize") - ->label(t("Organize album")) - ->css_class("ui-icon-folder-open g-organize-link") - ->url(url::site("organize/dialog/{$item->id}"))); + if (access::can("edit", $item)) { + if ($item->is_album()) { + $menu->get("options_menu") + ->append(Menu::factory("dialog") + ->id("organize") + ->label(t("Organize album")) + ->css_class("ui-icon-folder-open g-organize-link") + ->url(url::site("organize/dialog/{$item->id}"))); + } else { + $parent = $item->parent(); + $menu->get("options_menu") + ->append(Menu::factory("dialog") + ->id("move") + ->label(t("Move to another album")) + ->css_class("ui-icon-folder-open g-organize-link") + ->url(url::site("organize/dialog/{$parent->id}?selected_id={$item->id}"))); + } } } @@ -51,8 +61,7 @@ class organize_event_Core { static function module_change($changes) { if (!module::is_active("rest") || in_array("rest", $changes->deactivate)) { site_status::warning( - t("The Organize module requires the Rest module. " . - "<a href=\"%url\">Activate the Rest module now</a>", + t("The Organize module requires the Rest module. <a href=\"%url\">Activate the Rest module now</a>", array("url" => html::mark_clean(url::site("admin/modules")))), "organize_needs_rest"); } else { diff --git a/modules/organize/helpers/organize_installer.php b/modules/organize/helpers/organize_installer.php index bbe6fc65..2faa598b 100644 --- a/modules/organize/helpers/organize_installer.php +++ b/modules/organize/helpers/organize_installer.php @@ -22,12 +22,15 @@ class organize_installer { site_status::clear("organize_needs_rest"); } + static function install() { + module::set_version("organize", $version = 2); + } + static function upgrade($version) { if ($version == 1) { if (!module::is_active("rest")) { site_status::warning( - t("The Organize module requires the Rest module. " . - "<a href=\"%url\">Activate the Rest module now</a>", + t("The Organize module requires the Rest module. <a href=\"%url\">Activate the Rest module now</a>", array("url" => html::mark_clean(url::site("admin/modules")))), "organize_needs_rest"); } diff --git a/modules/organize/lib/Gallery3WebClient.swf b/modules/organize/lib/Gallery3WebClient.swf Binary files differindex b37a74c3..b82c8a42 100644 --- a/modules/organize/lib/Gallery3WebClient.swf +++ b/modules/organize/lib/Gallery3WebClient.swf diff --git a/modules/organize/views/organize_dialog.html.php b/modules/organize/views/organize_dialog.html.php index 4cc6385e..b76813ad 100644 --- a/modules/organize/views/organize_dialog.html.php +++ b/modules/organize/views/organize_dialog.html.php @@ -1,10 +1,6 @@ <?php defined("SYSPATH") or die("No direct script access.") ?> <script type="text/javascript" src="<?= url::file("lib/swfobject.js") ?>"></script> <style type="text/css" media="screen"> - #flashContent { - //display:none; - } - .g-organize { padding: 0; margins: 0; @@ -21,10 +17,10 @@ </style> <script type="text/javascript"> - $("#g-dialog").bind("dialogclose", function(event, ui) { - // @todo do a call to organize/closing to end the batch - window.location.reload(); - }); + $("#g-dialog").bind("dialogclose", function(event, ui) { + // @todo do a call to organize/closing to end the batch + window.location.reload(); + }); function closeOrganizeDialog() { $("#g-dialog").dialog("close"); @@ -94,6 +90,7 @@ sortOrder: "<?= $sort_order ?>", sortFields: "<?= $sort_fields ?>", albumId: "<?= $album->id ?>", + selectedId: "<?= $selected_id ?>", restUri: "<?= $rest_uri ?>", controllerUri: "<?= $controller_uri ?>" }; @@ -129,8 +126,7 @@ <h1 style="display:none"><?= t("Organize :: %name", array("name" => html::purify($album->title))) ?></h1> <div id="flashContent"> <p> - <?= t("To use the Organize feature, please ensure that Adobe Flash Player version %flash_minimum_version " . - "or greater is installed.", array("flash_minimum_version" => $flash_minimum_version)) ?> + <?= t("Your browser must have Adobe Flash Player version %flash_minimum_version or greater installed to use this feature.", array("flash_minimum_version" => $flash_minimum_version)) ?> </p> <a href="http://www.adobe.com/go/getflashplayer"> <img src="<?= request::protocol() ?>://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" diff --git a/modules/recaptcha/helpers/recaptcha_event.php b/modules/recaptcha/helpers/recaptcha_event.php index fda998e1..f185f92b 100644 --- a/modules/recaptcha/helpers/recaptcha_event.php +++ b/modules/recaptcha/helpers/recaptcha_event.php @@ -18,21 +18,17 @@ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ class recaptcha_event_Core { - static function user_profile_contact_form($form) { + static function captcha_protect_form($form) { if (module::get_var("recaptcha", "public_key")) { - $form->message->recaptcha("recaptcha")->label("")->id("g-recaptcha"); - } - } + foreach ($form->inputs as $input) { + if ($input instanceof Form_Group) { + $input->recaptcha("recaptcha")->label("")->id("g-recaptcha"); + return; + } + } - static function comment_add_form($form) { - if (module::get_var("recaptcha", "public_key")) { - $form->add_comment->recaptcha("recaptcha")->label("")->id("g-recaptcha"); - } - } - - static function register_add_form($form) { - if (module::get_var("recaptcha", "public_key")) { - $form->register_user->recaptcha("recaptcha")->label("")->id("g-recaptcha"); + // If we haven't returned yet, then add the captcha at the end of the form + $form->recaptcha("recaptcha")->label("")->id("g-recaptcha"); } } diff --git a/modules/slideshow/helpers/slideshow_event.php b/modules/slideshow/helpers/slideshow_event.php index 6cb5d019..167fa7ff 100644 --- a/modules/slideshow/helpers/slideshow_event.php +++ b/modules/slideshow/helpers/slideshow_event.php @@ -27,8 +27,7 @@ class slideshow_event_Core { static function module_change($changes) { if (!module::is_active("rss") || in_array("rss", $changes->deactivate)) { site_status::warning( - t("The Slideshow module requires the RSS module. " . - "<a href=\"%url\">Activate the RSS module now</a>", + t("The Slideshow module requires the RSS module. <a href=\"%url\">Activate the RSS module now</a>", array("url" => html::mark_clean(url::site("admin/modules")))), "slideshow_needs_rss"); } else { diff --git a/themes/admin_wind/css/screen.css b/themes/admin_wind/css/screen.css index 2ea60402..81b1a896 100644 --- a/themes/admin_wind/css/screen.css +++ b/themes/admin_wind/css/screen.css @@ -399,26 +399,6 @@ th { background-color: #FFF; } -/* Theme options ~~~~~~~~~~~~~~~~~~~~~~~~ */ -#g-theme-options-form { - border: 1px solid #a6c9e2; -} -#g-theme-options-form-tabs { - border: none !important; -} -#g-theme-options-form fieldset { - border: none; -} - -.ui-tabs .ui-tabs-nav li a { - padding: 0 1em; -} - -.ui-tabs .ui-tabs-nav li a.g-error { - background: none no-repeat scroll 0 0 transparent; - color: #FF0000 !important; -} - /* Language options ~~~~~~~~~~~~~~~~~~~~~~~~ */ #g-share-translations-form fieldset { border: 0px; diff --git a/themes/admin_wind/views/admin.html.php b/themes/admin_wind/views/admin.html.php index 6b0c3fe5..c4b51f41 100644 --- a/themes/admin_wind/views/admin.html.php +++ b/themes/admin_wind/views/admin.html.php @@ -11,7 +11,7 @@ <?= t("Admin dashboard") ?> <? endif ?> </title> - <link rel="shortcut icon" href="<?= url::file("lib/images/favicon.ico") ?>" type="image/x-icon" /> + <link rel="shortcut icon" href="<?= url::file(module::get_var("gallery", "favicon_url")) ?>" type="image/x-icon" /> <?= $theme->css("yui/reset-fonts-grids.css") ?> <?= $theme->css("themeroller/ui.base.css") ?> diff --git a/themes/wind/css/screen.css b/themes/wind/css/screen.css index be802976..2f91deaa 100644 --- a/themes/wind/css/screen.css +++ b/themes/wind/css/screen.css @@ -336,6 +336,15 @@ td { background-color: #cfc; } +#g-permissions .g-breadcrumbs a { + border: 1px solid #fff; +} + +#g-permissions .g-active a { + border: 1px solid #ddd; + background: #eee; +} + /** ******************************************************************* * 5) Navigation and menus *********************************************************************/ diff --git a/themes/wind/views/album.html.php b/themes/wind/views/album.html.php index 43565b45..ff069a84 100644 --- a/themes/wind/views/album.html.php +++ b/themes/wind/views/album.html.php @@ -16,7 +16,9 @@ <li id="g-item-id-<?= $child->id ?>" class="g-item <?= $item_class ?>"> <?= $theme->thumb_top($child) ?> <a href="<?= $child->url() ?>"> + <? if ($child->has_thumb()): ?> <?= $child->thumb_img(array("class" => "g-thumbnail")) ?> + <? endif ?> </a> <?= $theme->thumb_bottom($child) ?> <?= $theme->context_menu($child, "#g-item-id-{$child->id} .g-thumbnail") ?> diff --git a/themes/wind/views/page.html.php b/themes/wind/views/page.html.php index 9f94b04f..4938ed60 100644 --- a/themes/wind/views/page.html.php +++ b/themes/wind/views/page.html.php @@ -23,7 +23,7 @@ <? endif ?> <? endif ?> </title> - <link rel="shortcut icon" href="<?= url::file("lib/images/favicon.ico") ?>" type="image/x-icon" /> + <link rel="shortcut icon" href="<?= url::file(module::get_var("gallery", "favicon_url")) ?>" type="image/x-icon" /> <?= $theme->css("yui/reset-fonts-grids.css") ?> <?= $theme->css("superfish/css/superfish.css") ?> <?= $theme->css("themeroller/ui.base.css") ?> @@ -101,19 +101,22 @@ <? $i = 0 ?> <? foreach ($parents as $parent): ?> <li<? if ($i == 0) print " class=\"g-first\"" ?>> - <!-- Adding ?show=<id> causes Gallery3 to display the page - containing that photo. For now, we just do it for - the immediate parent so that when you go back up a - level you're on the right page. --> + <? // Adding ?show=<id> causes Gallery3 to display the page + // containing that photo. For now, we just do it for + // the immediate parent so that when you go back up a + // level you're on the right page. ?> <a href="<?= $parent->url($parent == $theme->item()->parent() ? "show={$theme->item()->id}" : null) ?>"> - <?= html::purify(text::limit_chars($parent->title, 15)) ?> + <!-- limit the title length to something reasonable (defaults to 15) --> + <?= html::purify(text::limit_chars($parent->title, + module::get_var("gallery", "visible_title_length"))) ?> </a> </li> <? $i++ ?> <? endforeach ?> <li class="g-active<? if ($i == 0) print " g-first" ?>"> - <?= html::purify(text::limit_chars($theme->item()->title, 15)) ?> + <?= html::purify(text::limit_chars($theme->item()->title, + module::get_var("gallery", "visible_title_length"))) ?> </li> </ul> <? endif ?> |