Differences

This shows you the differences between two versions of the page.

Link to this comparison view

dev:extensions:plugin_tutorial2 [2011/09/13 13:41]
plg Page moved from dev_documentation:plugin_tutorial2 to dev:plugin_tutorial2
— (current)
Line 1: Line 1:
-====== Plugin Tutorial: Several tricks from the Copyrights plugin ====== 
-In this tutorial you will learn more about the basics of plugin development for Piwigo. This tutorial is a follow up on [[:tutorial1|Tutorial: Hello World!]]. The entire plugin can be  
-installed from the extension gallery under the name [[http://piwigo.org/ext/extension_view.php?eid=537|'Copyrights']]. 
-Note that this tutorial follows the v1.0 revision of this plugin. 
  
-Since the plugin is relatively large to put all the code on this page, we only explicitly put that code here that is important and clarifies the ideas explained. The reader should read the rest of the code from the sources pointed to above. 
- 
-===== Introduction ===== 
-First of all, download the source code of the [[http://piwigo.org/ext/extension_view.php?eid=543|Skeleton plugin]]. We will use that as basis for this plugin. 
- 
-==== Outline ==== 
-With this plugin we want to achieve the following: 
-  - Somewhere we want to manage our copyrights. 
-  - Somehow copyrights must be added to photos. 
-  - Somehow the copyright must be displayed when visitors view a photo. 
-Therefore, we will write code for: 
-  - An administration panel, where the admin can create and edit plugins 
-  - An extension to the Batch manager (using events) so that copyrights can be added to photos. 
-  - Another event-hook that will display the copyright when a photo is viewed. 
- 
-===== The admin panel ===== 
- 
-For the admin panel we need to do two things. First add a link to the plugins menu, second create an admin page. 
- 
-==== The link in the menu ==== 
- 
-To add a link to the menu of plugins we put the following code in main.inc.php. This is our first serious encounter with event handlers. To see what events are available we refer to the [[http://piwigo.org/ext/extension_view.php?eid=288|Event tracer plugin]]. 
-<code php> 
-/* +-----------------------------------------------------------------------+ 
- * | Plugin admin                                                          | 
- * +-----------------------------------------------------------------------+ */ 
- 
-// Add an entry to the plugins menu 
-add_event_handler('get_admin_plugin_menu_links', 'copyrights_admin_menu'); 
-function copyrights_admin_menu($menu) { 
-  array_push( 
-    $menu, 
-    array( 
-      'NAME'  => 'Copyrights', 
-      'URL'   => get_admin_plugin_menu_link(dirname(__FILE__)).'/admin.php' 
-    ) 
-  ); 
-  return $menu; 
-} 
-</code> 
-This adds an event handler to the event 'get_admin_plugin_menu_links'. The added handler is the function 'copyrights_admin_menu' that we define right below it. It consists of a simple array_push() to add our link to the plugins menu. 
- 
-Lets move on to the content of admin.php, since that is what we are linking to. 
- 
-==== The admin page ==== 
-We would like to do several things on the admin page. First of all, we want to be able to create plugins. Next we should be able to view them, and lastly, we want to be able to edit existing copyrights. 
- 
-Firstly, however, we load the language file and perform a security check. 
-<code php> 
-load_language('plugin.lang', COPYRIGHTS_PATH); 
- 
-// Check access and exit when user status is not ok 
-check_status(ACCESS_ADMINISTRATOR); 
-</code> 
- 
-The rest of the code of the admin page does not add much to the learning of plugin writing for Piwigo. It is best read from source directly. The code is commented farely well. 
- 
-It is, however, good to mention the special use of the '$tab' variable. This is a variable that is used by Piwigo to create the tabbed layout they use. The Copyrights plugin makes use of this variable for deleting and updating Copyrights as if those are 'unvisible' tabs. 
- 
-===== Extending the Batch manager ===== 
-The Batch manager comes with two modes, so we will have to write extensions to both. 
- 
-==== Batch Mode ==== 
-Here we will again use event handlers to extend the functionality of Piwigo. We use two of them: 
-  * One to add the copyrights selector to the possible actions of the Batch Manager 
-  * The second to catch the 'Submit' button of the Batch Manager, and update the database 
- 
-<code php> 
-// Add copyrights drop down menu to the batch manager 
-add_event_handler('loc_end_element_set_global', 'copyrights_batch_global'); 
-// Add handler to the submit event of the batch manager 
-add_event_handler('element_set_global_action', 'copyrights_batch_global_submit', 50, 2); 
-</code> 
- 
-Now we should specify the contents of the functions 'copyrights_batch_global' and 'copyrights_batch_global_submit'. 
- 
-=== copyrights_batch_global === 
- 
-<code php> 
-function copyrights_batch_global() 
-{ 
-  global $template; 
- 
-  load_language('plugin.lang', dirname(__FILE__).'/'); 
- 
-  // Assign the template for batch management 
-  $template->set_filename('CR_batch_global', dirname(__FILE__).'/batch_global.tpl'); 
- 
-  // Fetch all the copyrights and assign them to the template 
-  $query = sprintf( 
-    'SELECT `cr_id`,`name` 
-    FROM %s 
-    WHERE `visible`<>0 
-    ;', 
-  COPYRIGHTS_ADMIN); 
-  $result = pwg_query($query); 
-  $CRoptions = array(); 
-  while ($row = pwg_db_fetch_assoc($result)) { 
-    $CRoptions[$row['cr_id']] = $row['name']; 
-  } 
-  $template->assign('CRoptions', $CRoptions); 
- 
- 
-  // Add info on the "choose action" dropdown in the batch manager 
-  $template->append('element_set_global_plugins_actions', array( 
-    'ID' => 'copyrights', // ID of the batch manager action 
-    'NAME' => l10n('Edit copyright'), // Description of the batch manager action 
-    'CONTENT' => $template->parse('CR_batch_global', true) 
-  ) 
-  ); 
-} 
-</code> 
-As can be seen, we again load the language file. Next we add the contents of 'batch_global.tpl' to the template and finally assign the list of copyrights obtained from the database to this template. 
- 
-The file 'batch_global.tpl' contains a small bit of Smarty code to create a copyright selector. 
-<code smarty> 
-<!-- Template for the copyright selector --> 
-<div id="copyrights"> 
- {'Copyright'|@translate} 
- <select name="copyrightID"> 
- <option value="0">--</option> 
- {html_options options=$CRoptions} 
- </select> 
-</div> 
-</code> 
- 
-=== copyrights_batch_global_submit === 
-When the 'Submit' button is clicked, an event is fired. We attached the following function to this event. 
-<code php> 
-// Process the submit action 
-function copyrights_batch_global_submit($action, $collection) 
-{ 
-  // If its our plugin that is called 
-  if ($action == 'copyrights') 
-  { 
-    $crID = pwg_db_real_escape_string($_POST['copyrightID']); 
- 
-    // Delete any previously assigned copyrights 
-    if (count($collection) > 0) { 
-      $query = sprintf( 
-        'DELETE 
-        FROM %s 
-        WHERE media_id IN (%s) 
-        ;', 
-      COPYRIGHTS_MEDIA, implode(',', $collection)); 
-      pwg_query($query); 
-    } 
- 
-    // Add the copyrights from the submit form to an array 
-    $edits = array(); 
-    foreach ($collection as $image_id) 
-    { 
-      array_push( 
-        $edits, 
-        array( 
-          'media_id' => $image_id, 
-          'cr_id' => $crID, 
-        ) 
-      ); 
-    } 
- 
-    // Insert the array into the database 
-    mass_inserts( 
-      COPYRIGHTS_MEDIA,       // Table name 
-      array_keys($edits[0]),  // Columns 
-      $edits                  // Data 
-    ); 
-  } 
-} 
-</code> 
-So we first check whether it was our action ('Edit copyright') was chosen in the action list of the Batch Manager. 
-If so, we obtain the chosen copyright id from the form $_POST variable. 
- 
-Next we assign the the copyrights to all photos in the $collection, by first deleting any previously made assignments, and afterwards inserting the whole bunch with Piwigo's mass_inserts function. 
- 
-==== Single Mode ==== 
-To extend the 'Single Mode' or 'Unit Mode' of the Batch Manager, we have to use prefilters. Prefilters are a really nifty feature of Smarty code. See [[http://www.smarty.net/docsv2/en/advanced.features.prefilters.tpl|their site]] for more information on all the functionality. 
- 
-When speaking for Piwigo, generally a prefilter can be attached to any file X.tpl that exists in the template folder. 
- 
-To attach a prefilter to such a file, one should find an event near to where the X.tpl is being used. This will be more clear below. 
- 
-== Setting the prefilter == 
-For the Copyrights plugin, we want to modify the Smarty code of the batch_manager_unit.tpl file. 
-We therefore use the following code. 
-<code php> 
-// Add event handlers for the prefilter 
-add_event_handler('loc_end_element_set_unit', 'CR_set_prefilter_batch_single', 55 ); 
-</code> 
-This attaches the function 'CR_set_prefilter_batch_single' to the event 'loc_end_element_set_unit' which is fired when Piwigo starts loading the Single Mode page of the Batch Manager. 
- 
-The event handler function then attaches a prefilter to batch_manager_unit.tpl. 
-<code php> 
-// Add a prefilter to the template 
-function CR_set_prefilter_batch_single() 
-{ 
-  global $template; 
-  $template->set_prefilter('batch_manager_unit', 'CR_batch_single'); 
-} 
-</code> 
-This means that when Smarty starts rendering batch_manager_unit.tpl, it will first execute CR_batch_single. 
- 
-That particular function will of course add the copyright selector to the page. 
-<code php> 
-// Insert the copyright selector to the template 
-function CR_batch_single($content, &$smarty) 
-{ 
-  $search = "#<td><strong>{'Creation date'#"; 
- 
-  // We use the <tr> from the Creation date, and give them a new <tr> 
-  $replacement = '<td><strong>{\'Copyright\'|@translate}</strong></td> 
-    <td> 
-      <select id="copyright-{$element.ID}" name="copyright-{$element.ID}"> 
-        <option value="0">--</option> 
-        {html_options options=$CRoptions selected=$CRcopyrights[$element.ID]} 
-      </select> 
-    </td> 
-  </tr> 
-   
-  <tr> 
-    <td><strong>{\'Creation date\''; 
- 
-  return preg_replace($search, $replacement, $content); 
-} 
-</code> 
- 
-== Assigning variables in Smarty == 
-Now that the Smarty code of the Single Mode is extended we obviously want to assign the variables. This can be done with another event handler. 
-<code php> 
-// Change the variables used by the function that changes the template 
-add_event_handler('loc_end_element_set_unit', 'CR_add_batch_single_vars_to_template'); 
-</code> 
-Now the smart reader might object that we have to event handlers attached to the same event, the one depending on the other. How do we assure that the prefilter is executed before we try to assign the variables? The even smarter reader might have noticed that the first event_handler line ended with ', 55 );'. This number 55 states the priority of the event handler, which defaults to 50. Hence the first event handler will indeed be executed before the second. 
- 
-The contents of the second event handler are as follows. 
-<code php> 
-// Assign the variables to the Smarty template 
-function CR_add_batch_single_vars_to_template() 
-{ 
-  global $template; 
- 
-  load_language('plugin.lang', dirname(__FILE__).'/'); 
- 
-  // Fetch all the copyrights and assign them to the template 
-  $query = sprintf( 
-    'SELECT `cr_id`,`name` 
-    FROM %s 
-    WHERE `visible`<>0 
-    ;', 
-    COPYRIGHTS_ADMIN); 
-  $result = pwg_query($query); 
- 
-  $CRoptions = array(); 
-  while ($row = pwg_db_fetch_assoc($result)) { 
-    $CRoptions[$row['cr_id']] = $row['name']; 
-  } 
-  $template->assign('CRoptions', $CRoptions); 
- 
-  // Get the copyright for each element 
-  $query = sprintf( 
-    'SELECT `media_id`, `cr_id` 
-    FROM %s 
-    ;', 
-    COPYRIGHTS_MEDIA); 
-  $result = pwg_query($query); 
- 
-  $CRcopyrights = array(); 
-  while ($row = pwg_db_fetch_assoc($result)) { 
-    $CRcopyrights[$row['media_id']] = $row['cr_id']; 
-  } 
- 
-  // Assign the copyrights to the template 
-  $template->assign('CRcopyrights', $CRcopyrights); 
-} 
-</code> 
-Note that we again load the language file. Furthermore we just select the visible copyrights from the database and assign them to the copyright selector. 
- 
-== Catching the 'Submit' == 
-Finally we want to really do something with the selected copyrights. So we will have to attach something to the submit button. We will again use an event handler. 
-<code php> 
-add_event_handler('loc_begin_element_set_unit', 'CR_batch_single_submit', 50 ); 
-</code> 
- 
-The content of this event handler checks whether the $_POST['submit'] variable is set. If so it executes some lines of code that very closely resemble the submit code for the Global Mode. 
-<code php> 
-// Catch the submit and update the copyrights tables 
-function CR_batch_single_submit() 
-{ 
-  if (isset($_POST['submit'])) 
-  { 
-    // The image id's: 
-    $collection = explode(',', $_POST['element_ids']); 
- 
-    // Delete all existing id's of which the copyright is going to be set 
-    if (count($collection) > 0) { 
-      $query = sprintf( 
-        'DELETE 
-        FROM %s 
-        WHERE media_id IN (%s) 
-        ;', 
-        COPYRIGHTS_MEDIA, implode(',', $collection)); 
-      pwg_query($query); 
-    } 
- 
-    // Add all copyrights to an array 
-    $edits = array(); 
-    foreach ($collection as $image_id) { 
-      // The copyright id's 
-      $crID = pwg_db_real_escape_string($_POST['copyright-'.$image_id]); 
- 
-      array_push( 
-        $edits, 
-        array( 
-          'media_id' => $image_id, 
- 
-    'cr_id' => $crID, 
-        ) 
-      ); 
-    } 
- 
-    // Insert the array to the database 
-    mass_inserts( 
-      COPYRIGHTS_MEDIA,        // Table name 
-      array_keys($edits[0]),   // Columns 
-      $edits                   // Data 
-    ); 
-  } 
-} 
-</code> 
- 
-===== Modifying copyrights via picture_modify.php ===== 
-This part of the plugin works in the same way as the single mode of the Batch Manager. 
-  - It attaches an event handler, to set a prefilter. 
-  - The prefilter adds some Smarty code to the template. 
-  - Another event handler assigns the variables in the Smarty code. 
-  - Yet another event handler catches the 'Submit' button and updates the database. 
-The reader should try to understand how this is done by looking at the source code of the plugin. 
- 
-===== Showing the copyrights to visitors ===== 
-To show the copyrights to people visiting the gallery, we again make use of a prefilter. Just like the ways mentioned above. It should by now be pretty straight forward to learn this from the source code. 
- 
-===== Using maintain.inc.php ===== 
-In the file maintain.inc.php one can put code that should be executed at install, activation or deletion of a plugin. The reader can see from the source code of the plugin that the Copyrights plugin inserts several default copyrights into the database by using this file. 
- 
-===== Conclusion ===== 
-One might have noticed from this tutorial that event handlers and in particular prefilters are a mighty tool in developing Piwigo extensions. Still it is difficult to cover everything in a single tutorial. Therefore, the reader should browse and study the source code of Piwigo itself and of other plugins, to gain a stronger sense of how to use these nifty features. 
-In particular, one should also read tutorials on Smarty. Note for example that besides prefilters there also exist postfilters! 
 
 
 
github twitter newsletter Donate Piwigo.org © 2002-2024 · Contact