Hi,
I've been working a lot with zenphoto and doing a lot of hacking, and my next task is to have an admin user (i've set this up, don't worry about that portion of it) be able to modify the descriptions of items (images, movies, subalbums, and other files) on the album.php and index.php files.
I've so far just brought in the printImageDesc() function, specifying "true" (so, printImageDesc(true)) into the While loop in album.php, to print editable descriptions of individual items. However, any description edits change the description of the album or subalbum the file/subalbum is contained within, not their own descriptions.
Does anyone know how I might target those descriptions rather than their parents?
Comments
I want to be able to edit all file's, folders, and subfolder descriptions in this way.
http://www.zenphoto.org/support/topic.php?id=1590&replies=6
I have a solution brewing in my mind. I think I need to pass another value into the printImageDesc(true) that tells the ajax script which file/album to edit. I'll have to keep passing that value through all the different functions until it finally hits the one where it dumps the values into the database.
It's more like a maze than a puzzle (like kenoji in that post said), haha.
I've been able to get to this work with limited success. I can edit subalbum names by querying the database, retrieving the album's id, and passing it through the following functions:
`printAlbumDesc(true, $albumID)` - album.php ->>
`initEditableDesc('albumDescEditable', $albumID)` - template_functions.php ->>
`x_SaveDesc(form.content.value, itemID, this.saveChangesCB)` - ajax.js ->>
`SaveDesc($newDesc, $itemID)` - controller.php ->>
`save($itemID, $type)` - classes.php ->>
You'll note that I change from $albumID to itemID at the x_SaveDesc function. This is because this function is shared by both image and album description updating.
Once I've passed the ID and type to save(), I see if the type is either a file or an album (I pass $type from the SaveDesc() function(s) in controller.php because there is one that handles albums and one that handles files). The query is then modified in save() to either update either the images table or the albums table, and to set the description of the ID that's been passed through since the start.
Problem is, this isn't working for files. I'm not totally sure why. I can get the file's ID, just as I can get the subalbum ID. I pass the variables all the same.
I may have gone beyond what I can be helped with here, but I'd gladly contribute the source for this once I get it working. Any help is greatly appreciated!
I'm working with a heavily modified "Audible" theme. These instructions will work for audible, but should also work for any theme that displays image descriptions outside of just image.php.
From album.php, in the themes/*yourtheme*/ directory, whenever I called the functions printImageDesc or printAlbumDesc, I would pass two values:
true - makes the div editable
albumID/imageID - the id, in the database, of that album.
I got the ID's by executing a few queries right on album.php. This probably isn't the best way to do this, but it works. The first query I run at the top of the document, just after the require_once() functions. This pulls the ID of the album that you're currently viewing, so that you're still able to edit the Album title and description on album.php:
`/// This code pulls the currently viewed album ID from the zp_albums table in the database so that we edit on-page with AJAX.
$folder = getAlbumLinkURL();
/// "clientzen" is the root zp install folder on the server. !!!!! Change the next line if the zp install is moved !!!!!
$folder = str_replace("/clientzen/index.php?album=", "", $folder);
$folder = str_replace("+", " ", $folder);
$folder = str_replace("%2F", "/", $folder);
/// The mysql query and result
$idQuery = "SELECT id FROM zp_albums WHERE folder = '$folder'";
$idResult = mysql_query($idQuery) or die(mysql_error());
while(list($id) = mysql_fetch_array($idResult, MYSQL_NUM)){
$currentAlbumID = $id + 0;}`
Since I'm using subalbums, I put some code and a query in the subalbum listing loop, to pull out the ID's of the subalbums.
`/// This code pulls the album ID from the zp_albums table in the database so that we edit on-page with AJAX.
$folder = getAlbumLinkURL();
/// 'clientzen' is the root zp install folder on the server. !!!!! Change the next line if the zp install is moved to a folder other than 'clientzen' !!!!!
$folder = str_replace("/clientzen/index.php?album=", "", $folder);
$folder = str_replace("+", " ", $folder);
$folder = str_replace("%2F", "/", $folder);
/// The mysql query and result
$idQuery = "SELECT id FROM zp_albums WHERE folder = '$folder'";
$idResult = mysql_query($idQuery) or die(mysql_error());
while(list($id) = mysql_fetch_array($idResult, MYSQL_NUM)){
$albumID = $id + 0;}
// Pass "true" here to enable editing, and $albumID so that zp will know which description to edit.
printAlbumDesc(true, $albumID);`
This code prints an editable div that will target that specific subalbum's description.
Lastly on album.php, I put this code in the Image/File loop to get ID's of the images/files:
`$filename = substr(strrchr($filename, "="), 1);
$filenameShort = str_replace("+", " ", $filename);
$filename = "./albums/".$album."/".$filenameShort;
/// The mysql query and result
$idQuery = "SELECT id FROM zp_images WHERE albumid = '$currentAlbumID' AND filename = '$filenameShort'";
$idResult = mysql_query($idQuery) or die(mysql_error());
while(list($id) = mysql_fetch_array($idResult, MYSQL_NUM)){
$fileID = $id + 0;}
// Pass "true" here to enable editing, and $fileID so that zp will know which description to edit.
printImageDesc(true, $fileID);`
In my file, I have "admin" checks throughout to make sure this code is only executed when the admin user is logged in. That's all for album.php.
Next, in template-functions.php (in the /zen/ directory), I changed two functions.
printAlbumDesc:
`function printAlbumDesc($editable=false, $albumID) {
global $_zp_current_album;
if ($editable) {
$type = "album";
echo "
echo "initEditableDesc('albumDescEditable', $albumID, '$type');";
} else {
echo getAlbumDesc();
}
}`
printImageDesc:
`function printImageDesc($editable=false, $fileID) {
global $_zp_current_image;
if ($editable) {
$type = "file";
echo "
echo "initEditableDesc('imageDescEditable', $fileID, '$type');";
} else {
echo getImageDesc();
}
}`
One thing to note when editing these functions. You won't be able to simply call
`printImageDesc()` or `printAlbumDesc()` to call the non-editable descriptions. Use
`printImageDesc(false, 0)` or `printAlbunDesc(false, 0)`.
Next, in /zen/ajax.js:
Search for:
`function initEditableDesc(divID)`
Replace with:
`function initEditableDesc(divID, itemID, type)`
Search for:
`x_saveDesc(form.content.value, this.saveChangesCB);`
Replace with:
`x_saveDesc(form.content.value, itemID, type, this.saveChangesCB);`
Next, /zen/controller.php:
Find the saveDesc function (mine's on line 61). Replace it with this:
` function saveDesc($newdesc, $itemID, $type) {
if (get_magic_quotes_gpc()) $newdesc = stripslashes($newdesc);
global $_zp_current_image, $_zp_current_album;
if (in_context(ZP_IMAGE)) {
$_zp_current_image->setDesc($newdesc);
$_zp_current_image->save($itemID, $type);
return $newdesc;
} else if (in_context(ZP_ALBUM)) {
$_zp_current_album->setDesc($newdesc);
$_zp_current_album->save($itemID, $type);
return $newdesc;
} else {
return false;
}
}`
Then, lastly, find in classes.php the "save()" function.
Search For:
`function save()`
Replace with:
`function save($id, $type)`
There is one major if/else statement in the save() function. Go to the else section. There should be a comment around there like "// Save the existing object (updates only) based on the existing id."
Replace that whole else statement with this:
` } else {
// Save the existing object (updates only) based on the existing id.
if (empty($this->updates)) {
return true;
} else {
if ($type == "file") { $sql = 'UPDATE *YOUR IMAGE TABLE* SET'; }
if ($type == "album") { $sql = 'UPDATE *YOUR ALBUM TABLE* SET'; }
$i = 0;
foreach ($this->updates as $col => $value) {
if ($i > 0) $sql .= ",";
$sql .= " '$col' = '". mysql_escape_string($value) . "'";
$this->data[$col] = $value;
$i++;
}
$sql .= ' WHERE id=' . $id . ';';
$success = query($sql);
if ($success == false || mysql_affected_rows() != 1) { return false; }
$this->updates = array();
}
}`
Obviously, replace *YOUR IMAGE TABLE* and *YOUR ALBUM TABLE* with...your image and album table names.
And...you should be done! This is a nice feature that doesn't fit quite into vanilla ZP installs, but for installs that use some different themes, this really reduces clicks and as such, the time it takes for you to manage your photos/files/albums.
http://www.aarongrando.com/files/screen.jpg
The short answer is no, features involving front-end editing are a dead issue for Zenphoto.
I did this a few months ago on a custom ZP theme I was playing with. What I did was adding a line in jquery.editinplace.js, which allowed me to make AJAX edit/update calls with an extra parameter containing the object I wanted to modify. It's quite straightforward to do if you read the documentation in the jquery.editinplace.js file. With the latest releases of zenphoto I guess it would be easier to create a plugin to do it...
Good luck,
- T
Can you provide a few more details? What was the extra parameter you passed in?
@sbillard
I understand the cross scripting risks you mention on the other thread, but for intranet sites, the front editing is a real time saver! All of my users want it.
Just some positive feedback, the users I work with love the interface and the software ^_^
But that is not the point at all. I simply said that we developers will not enhance this feature because of security and localalization problems it has. There is indeed no discussion on this point. But feel free to make whatever modifications you wish. Zenphoto is, after all, open source. But also do not be suprised that you will need to be dillegent in keeping your changes up with any release you choose to move to.
But that is not the point at all. I simply said that we developers will not enhance this feature because of security and localalization problems it has. There is indeed no discussion on this point. But feel free to make whatever modifications you wish. Zenphoto is, after all, open source. But also do not be suprised that you will need to be dillegent in keeping your changes up with any release you choose to move to.