development.rst 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. Development
  2. ===========
  3. What should I use to edit php code
  4. ----------------------------------
  5. There are two main options: text editor or `integrated development environment`_ (IDE).
  6. Text Editor
  7. ^^^^^^^^^^^
  8. If you are new to software development or do not have much experience with IDEs, using a text editor will get you up and running the quickest. At a minimum, you will want one that does syntax highlighting to make the code easier to read. If you think you might submit patches to the bug tracker, you will want to make sure that your text editor does not change line endings. If you are using Windows, `Notepad++`_ is a good choice. If you are on a Mac, TextWrangler_ is a popular choice. You could also give TextMate_ a try.
  9. Integrated Development Environment
  10. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  11. An IDE does just what it's name implies: it includes a set of tools that you would normally use separately. Most IDEs will include source code control which will allow you to directly commit and update your code from your cvs repository. It may have an FTP client built into it to make the transfer of files to a remote server easier. It will have syntax checking to catch errors before you try to execute the code on a server.
  12. The two most popular free IDEs for PHP developers are Eclipse_ and NetBeans_. Eclipse has two different plugins for working with PHP code: PDT_ and PHPEclipse_.
  13. .. _integrated development environment: http://en.wikipedia.org/wiki/Integrated_development_environment
  14. .. _Notepad++: http://notepad-plus-plus.org/
  15. .. _TextWrangler: http://www.barebones.com/products/textwrangler/index.html
  16. .. _TextMate: http://macromates.com/
  17. .. _Eclipse: http://www.eclipse.org/
  18. .. _NetBeans: http://netbeans.org/
  19. .. _PDT: http://www.eclipse.org/pdt/
  20. .. _PHPEclipse: http://www.phpeclipse.com/
  21. I don't like the wording of something in Elgg. How do I change it?
  22. ------------------------------------------------------------------
  23. The best way to do this is with a plugin.
  24. Create the plugin skeleton
  25. ^^^^^^^^^^^^^^^^^^^^^^^^^^
  26. :doc:`/guides/plugins/plugin-skeleton`
  27. Locate the string that you want to change
  28. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  29. All the strings that a user sees should be in the ``/languages`` directory or in a plugin's languages directory (``/mod/<plugin name>/languages``). This is done so that it is easy to change what language Elgg uses. For more information on this see the developer documentation on :doc:`/guides/i18n` .
  30. To find the string use ``grep`` or a text editor that provides searching through files to locate the string. (A good text editor for Windows is `Notepad++`_ ) Let's say we want to change the string "Add friend" to "Make a new friend". The ``grep`` command to find this string would be ``grep -r "Add friend" *``. Using `Notepad++`_ , you would use the "Find in files" command. You would search for the string, set the filter to ``*.php``, set the directory to the base directory of Elgg, and make sure it searches all subdirectories. You might want to set it to be case sensitive also.
  31. You should locate the string "Add friend" in ``/languages/en.php``. You should see something like this in the file:
  32. .. code:: php
  33. 'friend:add' => "Add friend",
  34. This means every time Elgg sees ``friend:add`` it replaces it with "Add friend". We want to change the definition of ``friend:add``.
  35. Override the string
  36. ^^^^^^^^^^^^^^^^^^^
  37. To override this definition, we will add a languages file to the plugin that we built in the first step.
  38. 1. Create a new directory: ``/mod/<your plugin name>/languages``
  39. 2. Create a file in that directory called ``en.php``
  40. 3. Add these lines to that file
  41. .. code:: php
  42. <?php
  43. return array(
  44. 'friend:add' => 'Make a new friend',
  45. );
  46. Make sure that you do not have any spaces or newlines before the ``<?php``.
  47. You're done now and should be able to enable the plugin and see the change. If you are override the language of a plugin, make sure your plugin is loaded after the one you are trying to modify. The loading order is determined in the Tools Administration page of the admin section. As you find more things that you'd like to change, you can keep adding them to this plugin.
  48. How do I find the code that does x?
  49. -----------------------------------
  50. The best way to find the code that does something that you would like to change is to use ``grep`` or a similar search tool. If you do not have ``grep`` as a part of your operating system, you will want to install a grep tool or use a text-editor/IDE that has good searching in files. `Notepad++`_ is a good choice for Windows users. `Eclipse`_ with PHP and `NetBeans`_ are good choices for any platform.
  51. String Example
  52. ^^^^^^^^^^^^^^
  53. Let's say that you want to find where the *Log In* box code is located. A string from the *Log In* box that should be fairly unique is ``Remember me``. ``Grep`` for that string. You will find that it is only used in the ``en.php`` file in the ``/languages`` directory. There it is used to define the :doc:`/guides/i18n` string ``user:persistent``. ``Grep`` for that string now. You will find it in two places: the same ``en.php`` language file and in ``/views/default/forms/login.php``. The latter defines the html code that makes up the *Log In* box.
  54. Action Example
  55. ^^^^^^^^^^^^^^
  56. Let's say that you want to find the code that is run when a user clicks on the *Save* button when arranging widgets on a profile page. View the Profile page for a test user. Use Firebug to drill down through the html of the page until you come to the action of the edit widgets form. You'll see the url from the base is ``action/widgets/move``.
  57. ``Grep`` on ``widgets/move`` and two files are returned. One is the JavaScript code for the widgets : ``/js/lib/ui.widgets.js``. The other one, ``/engine/lib/widgets.php``, is where the action is registered using ``elgg_register_action('widgets/reorder')``. You may not be familiar with that function in which case, you should look it up at the API reference. Do a search on the function and it returns the documentation on the function. This tells you that the action is in the default location since a file location was not specified. The default location for actions is ``/actions`` so you will find the file at ``/actions/widgets/move.php``.
  58. Debug mode
  59. ----------
  60. During the installation process you might have noticed a checkbox that controlled whether debug mode was turned on or off. This setting can also be changed on the Site Administration page. Debug mode writes a lot of extra data to your php log. For example, when running in this mode every query to the database is written to your logs. It may be useful for debugging a problem though it can produce an overwhelming amount of data that may not be related to the problem at all. You may want to experiment with this mode to understand what it does, but make sure you run Elgg in normal mode on a production server.
  61. .. warning::
  62. Because of the amount of data being logged, don't enable this on a production server as it can fill up the log files really quick.
  63. What goes into the log in debug mode?
  64. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  65. - All database queries
  66. - Database query profiling
  67. - Page generation time
  68. - Number of queries per page
  69. - List of plugin language files
  70. - Additional errors/warnings compared to normal mode (it's very rare for these types of errors to be related to any problem that you might be having)
  71. What does the data look like?
  72. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  73. .. code::
  74. [07-Mar-2009 14:27:20] Query cache invalidated
  75. [07-Mar-2009 14:27:20] ** GUID:1 loaded from DB
  76. [07-Mar-2009 14:27:20] SELECT * from elggentities where guid=1 and ( (1 = 1) and enabled='yes') results cached
  77. [07-Mar-2009 14:27:20] SELECT guid from elggsites_entity where guid = 1 results cached
  78. [07-Mar-2009 14:27:20] Query cache invalidated
  79. [07-Mar-2009 14:27:20] ** GUID:1 loaded from DB
  80. [07-Mar-2009 14:27:20] SELECT * from elggentities where guid=1 and ( (1 = 1) and enabled='yes') results cached
  81. [07-Mar-2009 14:27:20] ** GUID:1 loaded from DB
  82. [07-Mar-2009 14:27:20] SELECT * from elggentities where guid=1 and ( (1 = 1) and enabled='yes') results returned from cache
  83. [07-Mar-2009 14:27:20] ** Sub part of GUID:1 loaded from DB
  84. [07-Mar-2009 14:27:20] SELECT * from elggsites_entity where guid=1 results cached
  85. [07-Mar-2009 14:27:20] Query cache invalidated
  86. [07-Mar-2009 14:27:20] DEBUG: 2009-03-07 14:27:20 (MST): "Undefined index: user" in file /var/www/elgg/engine/lib/elgglib.php (line 62)
  87. [07-Mar-2009 14:27:20] DEBUG: 2009-03-07 14:27:20 (MST): "Undefined index: pass" in file /var/www/elgg/engine/lib/elgglib.php (line 62)
  88. [07-Mar-2009 14:27:20] ***************** DB PROFILING ********************
  89. [07-Mar-2009 14:27:20] 1 times: 'SELECT * from elggdatalists'
  90. [07-Mar-2009 14:27:20] 1 times: 'SELECT * from elggentities where guid=1 and ( (access_id in (2) or (owner_guid = -1) or (access_id = 0 and owner_guid = -1)) and enabled='yes')'
  91. ...
  92. [07-Mar-2009 14:27:20] 2 times: 'update elggmetadata set access_id = 2 where entity_guid = 1'
  93. [07-Mar-2009 14:27:20] 1 times: 'UPDATE elggentities set owner_guid='0', access_id='2', container_guid='0', time_updated='1236461868' WHERE guid=1'
  94. [07-Mar-2009 14:27:20] 1 times: 'SELECT guid from elggsites_entity where guid = 1'
  95. [07-Mar-2009 14:27:20] 1 times: 'UPDATE elggsites_entity set name='3124/944', description='', url='http://example.org/' where guid=1'
  96. [07-Mar-2009 14:27:20] 1 times: 'UPDATE elggusers_entity set prev_last_action = last_action, last_action = 1236461868 where guid = 2'
  97. [07-Mar-2009 14:27:20] DB Queries for this page: 56
  98. [07-Mar-2009 14:27:20] ***************************************************
  99. [07-Mar-2009 14:27:20] Page /action/admin/site/update_basic generated in 0.36997294426 seconds
  100. What events are triggered on every page load?
  101. ---------------------------------------------
  102. There are 5 :doc:`Elgg events </design/events>` that are triggered on every page load:
  103. 1. boot, system
  104. 2. plugins_boot, system
  105. 3. init, system
  106. 4. pagesetup, system
  107. 5. shutdown, system
  108. The *boot*, *system* event is triggered before the plugins get loaded. There does not appear to be any difference between the timing of the next two events: *plugins_boot*, *system* and *init*, *system* so plugins tend to use *init*, *system*. This event is triggered just after the plugins are loaded near the end of the boot script (``/engine/start.php``). The *pagesetup*, *system* event is thrown the first time ``elgg_view()`` is called. Some pages like the default ``index.php`` do not call ``elgg_view()`` so it is not triggered for them. The *shutdown*, *system* event is triggered after the page has been sent to the requester and is handled through the PHP function ``register_shutdown_function()``.
  109. There are :doc:`other events </guides/events-list>` that are triggered by the Elgg core but they happen occasionally (such as when a user logs in).
  110. What variables are reserved by Elgg?
  111. ------------------------------------
  112. - ``$CONFIG``
  113. - ``$vars``
  114. - ``$autofeed``
  115. - ``$_GET['action']`` / ``$_POST['action']``
  116. - ``$viewtype``
  117. Copy a plugin
  118. -------------
  119. There are many questions asked about how to copy a plugin. Let's say you want to copy the ``blog`` plugin in order to run one plugin called ``blog`` and another called ``poetry``. This is not difficult but it does require a lot of work. You would need to
  120. - change the directory name
  121. - change the names of every function (having two functions causes PHP to crash)
  122. - change the name of every view (so as not to override the views on the original plugin)
  123. - change any data model subtypes
  124. - change the language file
  125. - change anything else that was specific to the original plugin
  126. .. note::
  127. If you are trying to clone the ``groups`` plugin, you will have the additional difficulty that the group plugin does not set a subtype.