Beginning

The best way to learn PHPDevShell is to view the Example Plugin or the PHPDevShell plugin, it gives you a clear overview of how you would do things, however, I will continue to add to the simple documentation as much as possible. Also don't forget to view the documentation generated by PHPDocumentor.

PHPDevShell is a unique framework in the sense that you can start working on your project immediately! Yes its true, PHPDevShell has a very very easy learning curve, that was the whole idea of its creation. You don't need to learn a "new" language to be able to start using it.

Everything works really simple, and only examples are needed.

Please view the example plugin (within distribution package) file to see an example of how you can quickly create an application. You can also open all other admin plugin source files to see how it is done, they are used exactly in the same way as your plugins will work.

This file can be located in the downloaded package.

If you feel like becoming a documentor please PM me, I cannot do this as well as PHPDevShell already keeps me pretty busy.

This is how you would start using PHPDevShell:

1. Each script you create has its own unique permission set you can manage in the gui. So you can start with your script immediately. Lets take a look at how a typical script looks. I will use the PHPDevShell own plugin script where you add usergroups to the database.

Your scripts will have the same structure:

  1. // This method loads and checks security.
  2. (is_object($security)) ? $security->load_security() : exit('Access Denied!');
  3.  
  4. echo "Some PHP Here";
  5.  
  6. $HTML = <<<HTML
  7. <form action="{$navigation->self_url()}" method="post">
  8.   <tr>
  9.     <td>
  10.       ...Some HTML Here!
  11.     </td>
  12.   </tr>
  13. </form>
  14. HTML;

Can you see how easy it is structured, its still php as you know it.

2. After your script is done you can add it in the menu manager, give it permission and you are all set.

Alternatively you could create a plugin for your script which enables users to install your scripts as a plugin.

More advanced...

I did not see the need to create a system that quickly generates forms through different code as it is not only limiting in many factors, but is PHP and HTML not already easy enough? It simply takes to long to learn different code for creating the same forms on different frameworks. Therefore we sticked with basic HTML.

This is a actual example phonebook script to have a simple form, with hook points, mandatory and error checking, basically everything as you would need it.

  1. /**
  2.  * PHPDevShell is a RAD Framework aimed at developing administrative applications.
  3.  *
  4.  * @package PHPDevShell
  5.  * @link <a href="http://www.phpdevshell.org<br />
  6. " title="http://www.phpdevshell.org<br />
  7. ">http://www.phpdevshell.org<br />
  8. </a> * @copyright Copyright (C) 2007 Jason Schoeman, All rights reserved.
  9.  * @license GNU/LGPL, see readme/licensed_under_lgpl or <a href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html<br />
  10. " title="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html<br />
  11. ">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html<br />
  12. </a> * @author Jason Schoeman, Contact: titan [at] phpdevshell [dot] org.
  13.  *
  14.  * Copyright notice: See readme/notice
  15.  * By using PHPDevShell you agree to notice and license, if you dont agree to this notice/license you are not allowed to use PHPDevShell.
  16.  */
  17.  
  18. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  19. // Security //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  20. // This method loads and checks security. ////////////////////////////////////////////////////////////////////////////////
  21. (is_object($security)) ? $security->load_security() : exit('Access Denied!'); ////////////////////////////////////////////
  22. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  23.  
  24. // This will give you a better understand of how simple it is creating scripts for PHPDevShell.
  25. // However, for advanced examples view the PHPDevShell plugin scripts, beware when opening them though,
  26. // you might change something and make PHPDevShell unstable, use hooks to integrate with core scripts.
  27.  
  28. //====>>>>
  29. $template->hook('head');
  30. //====>>>>
  31.  
  32. // Check if we are in edit or safe mode.
  33. if (!empty($_GET['epb']) || $_POST['save'])
  34. {
  35.         // Set heading and info text.
  36.         $template->heading(__('Edit Phonebook Entry'));
  37.         $template->info(__('Edit existing phonebook entries from here.'));
  38.         //====>>>>
  39.         $template->hook('header');
  40.         //====>>>>
  41.  
  42.         // If item is in edit mode.
  43.         if (!empty($_GET['epb']))
  44.         {
  45.                 // Call record that we need to edit.
  46.                 $select_phonebookentry = $db->new_query
  47.                 ("
  48.                         SELECT
  49.                                 t1.user_id, t1.cell_number, t1.work_number, t1.fax_number, t1.home_number,
  50.                                 t2.user_display_name
  51.                         FROM
  52.                                 _db_simple_phonebook t1
  53.                         LEFT JOIN
  54.                                 _db_core_users t2
  55.                         ON
  56.                                 t1.user_id = t2.user_id
  57.                         WHERE
  58.                                 t1.user_id = '$_GET[epb]'
  59.                 ");
  60.  
  61.                 $select_phonebookentry_array = mysql_fetch_array($select_phonebookentry);
  62.  
  63.                 $user_id           = $select_phonebookentry_array['user_id'];
  64.                 $cell_number       = $select_phonebookentry_array['cell_number'];
  65.                 $work_number       = $select_phonebookentry_array['work_number'];
  66.                 $fax_number        = $select_phonebookentry_array['fax_number'];
  67.                 $home_number       = $select_phonebookentry_array['home_number'];
  68.                 $user_display_name = $select_phonebookentry_array['user_display_name'];
  69.  
  70.                 //====>>>>
  71.                 $template->hook('on_edit');
  72.                 //====>>>>
  73.  
  74.         }
  75.  
  76.         // Whent the item gets saved.
  77.         if ($_POST['save'])
  78.         {
  79.                 $user_id           = $_POST['user_id'];
  80.                 $cell_number       = $_POST['cell_number'];
  81.                 $work_number       = $_POST['work_number'];
  82.                 $fax_number        = $_POST['fax_number'];
  83.                 $home_number       = $_POST['home_number'];
  84.                 $user_display_name = $_POST['user_display_name'];
  85.  
  86.                 //====>>>>
  87.                 $template->hook('on_submit');
  88.                 //====>>>>
  89.  
  90.                 // Check required fields.
  91.                 if (!empty($template->global['hook_field_error']) || empty($cell_number) && empty($work_number) && empty($home_number))
  92.                 {
  93.                         $template->warning(__('Oops, you must give at least one number excluding fax number before I will update phonebook database.'));
  94.                 }
  95.                 else
  96.                 {
  97.                         //====>>>>
  98.                         $template->hook('before_update');
  99.                         //====>>>>
  100.  
  101.                         // Insert into the database.
  102.                         $db->new_query
  103.                         ("
  104.                                 REPLACE INTO
  105.                                         _db_simple_phonebook (user_id, cell_number, work_number, fax_number, home_number)
  106.                                 VALUES
  107.                                         ('$user_id', '$cell_number', '$work_number', '$fax_number', '$home_number')
  108.                         ");
  109.  
  110.                         // Set variable global for hooks.
  111.                         $template->global['user_id'] = $user_id;
  112.  
  113.                         //====>>>>
  114.                         $template->hook('on_update');
  115.                         //====>>>>
  116.  
  117.                         // Show item updated.
  118.                         $template->ok(sprintf(__('I have changed user %s contacts in phonebook database.'), $user_display_name));
  119.  
  120.                 }
  121.         }
  122. }
  123. else
  124. {
  125.         // Show this heading if it is a new entry.
  126.         $template->heading(__('Add Phonebook Entry'));
  127.         $template->info(__('Add new phonebook entries from here.'));
  128.         //====>>>>
  129.         $template->hook('header');
  130.         //====>>>>
  131. }
  132.  
  133. // Lets add a nice logo!
  134. $template->note($lang['simplephonebook']);
  135.  
  136. //====>>>>
  137. $template->hook('head_html');
  138. //====>>>>
  139.  
  140. // Create the HTML!
  141. $HTML = <<<HTML
  142.         <form action="{$navigation->self_url()}" method="post">
  143.                 {$template->hook('top_html')}
  144.                 <tr>
  145.                         <td width="20%">
  146.                                 {$core->__('User ID')}
  147.                         </td>
  148.                         <td width="80%">
  149.                                 <input type="text" size="5" name="user_id" value="$user_id" class="boxdisabled" readonly>
  150.                                 {$template->info_mark(__('User ID auto generated by the system.'))}
  151.                         </td>
  152.                 </tr>
  153.                 <tr>
  154.                         <td>
  155.                                 {$core->__('Name of user')}
  156.                         </td>
  157.                         <td>
  158.                                 <input type="text" size="20" name="user_display_name" value="$user_display_name" class="boxdisabled" readonly>
  159.                                 {$template->info_mark(__('Name of user being edited.'))}
  160.                         </td>
  161.                 </tr>
  162.                 <tr>
  163.                         <td>
  164.                                 {$core->__('Cell Number')}
  165.                         </td>
  166.                         <td>
  167.                                 <input type="text" size="20" name="cell_number" value="$cell_number" class="boxnormal">
  168.                                 {$template->info_mark(__('Enter users Cell Number'))}
  169.                         </td>
  170.                 </tr>
  171.                 <tr>
  172.                         <td>
  173.                                 {$core->__('Work Number')}
  174.                         </td>
  175.                         <td>
  176.                                 <input type="text" size="20" name="work_number" value="$work_number" class="boxnormal">
  177.                                 {$template->info_mark(__('Enter users Work Number'))}
  178.                         </td>
  179.                 </tr>
  180.                 <tr>
  181.                         <td>
  182.                                 {$core->__('Fax Number')}
  183.                         </td>
  184.                         <td>
  185.                                 <input type="text" size="20" name="fax_number" value="$fax_number" class="boxnormal">
  186.                                 {$template->info_mark(__('Your Fax Number'))}
  187.                         </td>
  188.                 </tr>
  189.                 <tr>
  190.                         <td>
  191.                                 {$core->__('Home Number')}
  192.                         </td>
  193.                         <td>
  194.                                 <input type="text" size="20" name="home_number" value="$home_number" class="boxnormal">
  195.                                 {$template->info_mark(__('Your Home Number'))}
  196.                         </td>
  197.                 </tr>
  198.                 {$template->hook('bottom_html')}
  199.                 <tr>
  200.                         <td class="end" colspan="2">
  201.                                 <input type="submit" value="$lang[save]" name="save" class="button">
  202.                                 <input type="reset" value="$lang[reset]" class="button">
  203.                                 <input type="submit" value="$lang[new]" name="new" class="button">
  204.                         </td>
  205.                 </tr>
  206.         </form>
  207. HTML;
  208.  
  209. //====>>>>
  210. $template->hook('foot');
  211. //====>>>>

As you can see, very standard PHP code is used and HTML as you know it, making the learning curve very easy.

Plugins and Menus...

PHPDevShell works on a per script basis, so you would call above script something like add_phone_entry.php, ad it as a menu item through the GUI, or create an easy plugin for all your scripts like to be grouped together.

Below is an example of how a actual plugin config file will look;

  1. /**
  2.  * PHPDevShell is a RAD Framework aimed at developing administrative applications.
  3.  *
  4.  * @package PHPDevShell
  5.  * @link <a href="http://www.phpdevshell.org<br />
  6. " title="http://www.phpdevshell.org<br />
  7. ">http://www.phpdevshell.org<br />
  8. </a> * @copyright Copyright (C) 2007 Jason Schoeman, All rights reserved.
  9.  * @license GNU/LGPL, see readme/licensed_under_lgpl or <a href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html<br />
  10. " title="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html<br />
  11. ">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html<br />
  12. </a> * @author Jason Schoeman, Contact: titan [at] phpdevshell [dot] org.
  13.  *
  14.  * Copyright notice: See readme/notice
  15.  * By using PHPDevShell you agree to notice and license, if you dont agree to this notice/license you are not allowed to use PHPDevShell.
  16.  */
  17.  
  18. ////////////////////////////////////////////////////////////////////////////////////////
  19. // Plugin config file //////////////////////////////////////////////////////////////////
  20. ////////////////////////////////////////////////////////////////////////////////////////
  21.  
  22. ////////////////////////////////////////////////////////////////////////////////////////
  23. // Name you would like to give your plugin.
  24. $plugin['plugin_name']
  25. = 'Simple Phonebook';
  26.  
  27. ////////////////////////////////////////////////////////////////////////////////////////
  28. // The version like the end user will see it, like "V0.4.5-RC1".
  29. $plugin['software_version']
  30. = 'Simple Phonebook V 0.0.5-Demo';
  31.  
  32. ////////////////////////////////////////////////////////////////////////////////////////
  33. // a Description of your plugin. What does it do.
  34. $plugin['plugin_description']
  35. =
  36. '
  37. Simple Phonebook allows you to enter phone numbers in a phonebook database.
  38. ';
  39.  
  40. ////////////////////////////////////////////////////////////////////////////////////////
  41. // If it is a modified plugin, give the original author here.
  42. $plugin['original_author_name']
  43. = 'Jason Schoeman';
  44.  
  45. ////////////////////////////////////////////////////////////////////////////////////////
  46. // If you are the author of the plugin, write your name here.
  47. $plugin['author_name']
  48. = 'Jason Schoeman';
  49.  
  50. ////////////////////////////////////////////////////////////////////////////////////////
  51. // Email address of author.
  52. $plugin['author_email']
  53. = 'titan@phpdevshell.org';
  54.  
  55. ////////////////////////////////////////////////////////////////////////////////////////
  56. // Website of the author.
  57. $plugin['author_url']
  58. = 'http://www.phpdevshell.org';
  59.  
  60. ////////////////////////////////////////////////////////////////////////////////////////
  61. // Date plugin was created.
  62. $plugin['create_date']
  63. = '13 February 2008';
  64.  
  65. ////////////////////////////////////////////////////////////////////////////////////////
  66. // Copyright notice.
  67. $plugin['copyright']
  68. = 'Copyright &copy; 2007 PHPDevShell.org All rights reserved.';
  69.  
  70. ////////////////////////////////////////////////////////////////////////////////////////
  71. // Release license.
  72. $plugin['license']
  73. = 'http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU/LGPL';
  74.  
  75. ////////////////////////////////////////////////////////////////////////////////////////
  76. // The plugin version to use for upgrades.
  77. // Please READ!
  78. // This is what the system will use to create database updates from, when a user copies a newer version of a plugin,
  79. // the system will use this number to upgrade from what the user have, to the latest database version.
  80. // -------------------------------------------------------------------------------------
  81. // Say I have database version 2 installed, and you bring out a database update of 4 and I upgrade, the system will run,
  82. // all upwards database queries from version 2. If nothing is installed all queries from first version will be installed freshly.
  83. $plugin['database_version']
  84. = 1;
  85.  
  86. ////////////////////////////////////////////////////////////////////////////////////////
  87. // Query to run on activation, lower value arrays will be executed first.
  88. // The example queries below shows how you would go ahead to update your plugins database.
  89. // This is database version 1.
  90. // PS You cant put multiple sql queries in one array!
  91. $plugin['db_query_install'][1][1]
  92. = <<<SQL
  93.         CREATE TABLE `pds_simple_phonebook` (
  94.           `user_id` int(20) unsigned NOT NULL auto_increment,
  95.           `cell_number` varchar(255) default NULL,
  96.           `home_number` varchar(255) default NULL,
  97.           `work_number` varchar(255) default NULL,
  98.           `fax_number` varchar(255) default NULL,
  99.           PRIMARY KEY  (`user_id`)
  100.         ) ENGINE=MyISAM AUTO_INCREMENT=154 DEFAULT CHARSET=latin1;
  101. SQL;
  102.  
  103. // Still database 1 but entry next query.
  104. $plugin['db_query_install'][1][2]
  105. = <<<SQL
  106.         INSERT INTO `pds_simple_phonebook` VALUES ('1', '+2713 333 cell', '+2712 012 home', '+2712 012 work', '+2712 012 ifax');
  107. SQL;
  108.  
  109. // Example : When an update is released, EXAMPLE : change $plugin['database_version'] to 2 and check it out, user will now be able to upgrade from plugin manager.
  110. // Note how the array integers changed, this will now install the next sql scripts from here and will skip above queries when upgrading.
  111. // You can used advanced queries here as well!
  112. // Below will not run until $plugin['database_version'] is set to 2 or 3.
  113. $plugin['db_query_install'][2][1]
  114. = <<<SQL
  115.                 REPLACE INTO `pds_simple_phonebook` VALUES ('111', '+2712 012 cell', '+2712 012 home', '+2712 012 work', '+2712 012 ifax');
  116. SQL;
  117. $plugin['db_query_install'][2][2]
  118. = <<<SQL
  119.                 REPLACE INTO `pds_simple_phonebook` VALUES ('112', '+2712 012 cell', '+2712 012 home', '+2712 012 work', '+2712 012 ifax');
  120. SQL;
  121.  
  122. // Below will not run until $plugin['database_version'] is set to 2 or 3.
  123. // If other options like write_settings goes beyond the db_query_install, then fill db_query_install up with blanks to match the same number.
  124. $plugin['db_query_install'][3][1] = '';
  125.  
  126. // You could also install general plugin configuration settings.
  127. $plugin['write_settings'][1][1] = array('setting_1'=>'some_value_1', 'setting_2'=>'some_value_2', 'setting_3'=>'some_value_3');
  128. // And on updates, you can add more settings.
  129. // Below will not run until $plugin['database_version'] is set to 2 or 3.
  130. $plugin['write_settings'][2][1] = array('setting_3'=>'some_value_8');
  131. // We can issue a delete settings like this.
  132. $plugin['delete_settings'][3][1] = array('setting_1', 'setting_2');
  133.  
  134. // If you have some menu items to delete on an upgrade, you can do the following:
  135. // Sometimes you don't need a menu item anymore, and might want to delete it on next upgrade.
  136. // Issue menu delete command.
  137. // Below will not run until $plugin['database_version'] is set to 2 or 3.
  138. $plugin['delete_menus'][3][1] = array(1684409841);
  139.  
  140. // PS. Hooks does not to be deleted seperately as it simply re-installs the latest available hook list.
  141.  
  142. ////////////////////////////////////////////////////////////////////////////////////////
  143. // Query to run on deactivation.
  144. // Uninstall is simple, it will always use the latest uninstall script, the user will first need to upgrade first,
  145. // before he will be able to uninstall if it is a newer script.
  146. $plugin['db_query_uninstall'][1]
  147. = <<<SQL
  148.         DROP TABLE IF EXISTS pds_simple_phonebook
  149. SQL;
  150.  
  151. // You can continue with uninstall tables like below.
  152. /**
  153. $plugin['db_query_uninstall'][2]
  154. = <<<SQL
  155.         DROP TABLE IF EXISTS pds_simple_phonebook
  156. SQL;
  157. */
  158.  
  159. ////////////////////////////////////////////////////////////////////////////////////////
  160. // Menu items to include in menu structure, will have a ranking as per rank in array.
  161. // In folder item, no front or trailing slashes required, could be like example2/example3/example4.
  162.  
  163. // PS TEMPLATE : For the template option, leave blank 'template'=>'' to use default template, or use 'template'=>'empty' to set template as empty, user 'template'=>'your_custom_template_folder' for custom template.
  164. // When using a custom template will automatically create a template in the template manager, you must make sure the template files are under /templates though.
  165. $plugin['menu'][]
  166. = array('filename'=>'list_entries.php', 'deeper_folder'=>'', 'parent_filename'=>'', 'menu_visible'=>true, 'new_window'=>false, 'template'=>'');