]> git.mxchange.org Git - friendica.git/commitdiff
Add new documentation page about moving classes to src
authorHypolite Petovan <mrpetovan@gmail.com>
Sun, 30 Apr 2017 21:34:23 +0000 (17:34 -0400)
committerHypolite Petovan <mrpetovan@gmail.com>
Wed, 3 May 2017 03:37:40 +0000 (23:37 -0400)
doc/Composer.md
doc/Developer-How-To-Move-Classes-to-src.md [new file with mode: 0644]
doc/Developers-Intro.md
doc/Home.md
doc/autoloader.md
mod/help.php
view/theme/frio/css/style.css

index 8310baf3f0cfa67bd3ed7150c68f2f5cce1a5365..02ce61639cda4fabaad0ba8ec4e55a6844d1d002 100644 (file)
@@ -113,3 +113,8 @@ For Composer, this would be:
 ````
 $> COMPOSER_HOME=/var/tmp/composer sudo -u [web user] util/composer.phar [mode]
 ````
+
+## Related
+
+* [Class autoloading](help/autoloader)
+* [How To Move Classes to `src`](help/Developer-How-To-Move-Classes-to-src)
diff --git a/doc/Developer-How-To-Move-Classes-to-src.md b/doc/Developer-How-To-Move-Classes-to-src.md
new file mode 100644 (file)
index 0000000..d502e86
--- /dev/null
@@ -0,0 +1,105 @@
+How To Move Classes to `src`
+==============
+
+* [Home](help)
+  * [Developer Intro](help/Developers-Intro)
+
+Since April 2017, Friendica uses [Composer](help/Composer) to manage autoloading.
+This means that all the PHP class files moved to the `src` folder will be [automatically included](help/autoloader) when the class it defines is first used in the flow.
+This is an improvement over the current `require` usage since files will be included on an actual usage basis instead of the presence of a `require` call.
+
+However, there are a significant number of items to check when moving a class file from the `include` folder to the `src` folder, and this page is there to list them.
+
+## Decide the namespace
+
+This isn't the most technical decision of them all, but it has long lasting consequences as it will be the name that will be used to refer to this class from now on.
+There is [a shared Ethercalc sheet](https://ethercalc.org/friendica_classes) to suggest namespace/class names that lists all the already moved class files for inspiration.
+
+A few pointers though:
+* `Friendica` is the base namespace for all classes in the `src` folder
+* Namespaces match the directory structure, with `Friendica` namespace being the base `src` directory. The `Config` class set in the `Friendica\Core` namespace is expected to be found at `src/Core/Config.php`.
+* Namespaces can help group classes with a similar purpose or relevant to a particular feature
+
+When you're done deciding the namespace, it's time to use it.
+Let's say we choose `Friendica\Core` for the `Config` class.
+
+## Use the namespace
+
+To declare the namespace, the file `src/Core/Config.php` must start with the following statement:
+
+````php
+namespace Friendica\Core;
+````
+
+From now on, the `Config` class can be referred to as `Friendica\Core\Config`, however it isn't very practical, especially when the class was previously used as `Config`.
+Thankfully, PHP provides namespace shortcuts through `use`.
+
+This language construct just provides a different naming scheme for a namespace or a class, but doesn't trigger the autoload mechanism on its own.
+Here are the different ways you can use `use`:
+
+````php
+// No use
+$config = new Friendica\Core\Config();
+````
+````php
+// Namespace shortcut
+use Friendica\Core;
+
+$config = new Core\Config();
+````
+````php
+// Class name shortcut
+use Friendica\Core\Config;
+
+$config = new Config();
+````
+````php
+// Aliasing
+use Friendica\Core\Config as Cfg;
+
+$config = new Cfg();
+````
+
+Whatever the style chosen, a repository-wide search has to be done to find all the class name usage and either use the fully-qualified class name (including the namespace) or add a `use` statement at the start of each relevant file.
+
+## Escape non-namespace classes
+
+The class file you just moved is now in the `Friendica` namespace, but it probably isn't the case for all the classes referenced in this file.
+Since we added a `namespace Friendica\Core;` to the file, all the class names still declared in `include` will be implicitly understood as `Friendica\Core\ClassName`, which is rarely what we expect.
+
+To avoid `Class Friendica\Core\ClassName not found` errors, all the `include`-declared class names have to be prepended with a `\`, it tells the autoloader not to look for the class in the namespace but in the global space where non-namespaced classes are set.
+If there are only a handful of references to a single non-namespaced class, just prepending `\` is enough. However, if there are many instance, we can use `use` again.
+
+````php
+namespace Friendica\Core;
+...
+if (\dbm::is_result($r)) {
+    ...
+}
+````
+````php
+namespace Friendica\Core;
+
+use \dbm;
+
+if (dbm::is_result($r)) {
+    ...
+}
+````
+
+## Remove any useless `require`
+
+Now that you successfully moved your class to the autoloaded `src` folder, there's no need to include this file anywhere in the app ever again.
+Please remove all the `require_once` mentions of the former file, as they will provoke a Fatal Error even if the class isn't used.
+
+## Miscellaneous tips
+
+When you are done with moving the class, please run `php util/typo.php` from the Friendica base directory to check for obvious mistakes.
+Howevever, this tool isn't bullet-proof, and a staging install of Friendica is recommended to test your class move without impairing your production server if you host one.
+
+Most of Friendica processes are run in the background, so make sure to turn on your debug log to check for errors that wouldn't show up while simply browsing Friendica.
+
+## Related
+
+* [Class autoloading](help/autoloader)
+* [Using Composer](help/Composer)
\ No newline at end of file
index 5568afeb5da9e64b04eed0005ba0b1141d4717bb..3cda8ab4662b96bac0a3a5c75b3c5df025cfe9e3 100644 (file)
@@ -52,7 +52,9 @@ Friendica uses [Composer](https://getcomposer.org) to manage dependencies librar
 
 It's a command-line tool that downloads required libraries into the `vendor` folder and makes any namespaced class in `src` available through the whole application through `boot.php`.
 
+* [Class autoloading](help/autoloader)
 * [Using Composer](help/Composer)
+* [How To Move Classes to `src`](help/Developer-How-To-Move-Classes-to-src)
 
 ###Coding standards
 
index 5490d171f8f02c47a7ec35c2a379562399838117..4cecec44e3f2b46c095731426110af3ac390aef7 100644 (file)
@@ -36,21 +36,25 @@ Friendica Documentation and Resources
 
 **Developer Manual**
 
-* [Where to get started?](help/Developers-Intro)
-* [Help on Github](help/Github)
-* [Help on Vagrant](help/Vagrant)
-* [How to translate Friendica](help/translations)
-* [Bugs and Issues](help/Bugs-and-Issues)
-* [Plugin Development](help/Plugins)
-* [Theme Development](help/themes)
-* [Smarty 3 Templates](help/smarty3-templates)
-* [Protocol Documentation](help/Protocol)
-* [Database schema documantation](help/database)
-* [Class Autoloading](help/autoloader)
-* [Using Composer](help/Composer)
-* [Code - Reference(Doxygen generated - sets cookies)](doc/html/)
-* [Twitter/GNU Social API Functions](help/api)
-
+* [Get started](help/Developers-Intro)
+* Set up development environment
+       * [Help on Github](help/Github)
+       * [Help on Vagrant](help/Vagrant)
+       * [Bugs and Issues](help/Bugs-and-Issues)
+* Code structure
+       * [Plugin Development](help/Plugins)
+       * [Theme Development](help/themes)
+       * [Smarty 3 Templates](help/smarty3-templates)
+* How To
+       * [Translate Friendica](help/translations)
+       * [Use Composer](help/Composer)
+       * [Move classes to `src`](help/Developer-How-To-Move-Classes-to-src)
+* Reference
+       * [Twitter/GNU Social API Functions](help/api)
+       * [Code (Doxygen generated - sets cookies)](doc/html/)
+       * [Protocol Documentation](help/Protocol)
+       * [Database schema documantation](help/database)
+       * [Class Autoloading](help/autoloader)
 
 **External Resources**
 
index 83f1010440694cf0fb2109afcf86a11dedcc38ce..af76cf329969dafb3d02cc5d126f136306869557 100644 (file)
@@ -24,14 +24,14 @@ For more info about PHP autoloading, please refer to the [official PHP documenta
 Let's say you have a PHP file in `src/` that define a very useful class:\r
 \r
 ```php\r
-       // src/ItemsManager.php\r
-       <?php\r
-       namespace \Friendica;\r
-\r
-       class ItemsManager {\r
-               public function getAll() { ... }\r
-               public function getByID($id) { ... }\r
-       }\r
+// src/ItemsManager.php\r
+<?php\r
+namespace Friendica;\r
+\r
+class ItemsManager {\r
+       public function getAll() { ... }\r
+       public function getByID($id) { ... }\r
+}\r
 ```\r
 \r
 The class `ItemsManager` has been declared in the `Friendica` namespace.\r
@@ -43,16 +43,16 @@ In order for the Composer autoloader to work, it must first be included. In Frie
 The code will be something like:\r
 \r
 ```php\r
-       // mod/network.php\r
-       <?php\r
+// mod/network.php\r
+<?php\r
 \r
-       function network_content(App $a) {\r
-               $itemsmanager = new \Friendica\ItemsManager();\r
-               $items = $itemsmanager->getAll();\r
+function network_content(App $a) {\r
+       $itemsmanager = new Friendica\ItemsManager();\r
+       $items = $itemsmanager->getAll();\r
 \r
-               // pass $items to template\r
-               // return result\r
-       }\r
+       // pass $items to template\r
+       // return result\r
+}\r
 ```\r
 \r
 That's a quite simple example, but look: no `require()`!\r
@@ -61,132 +61,137 @@ If you need to use a class, you can simply use it and you don't need to do anyth
 Going further: now we have a bunch of `*Manager` classes that cause some code duplication, let's define a `BaseManager` class, where we move all common code between all managers:\r
 \r
 ```php\r
-       // src/BaseManager.php\r
-       <?php\r
-       namespace \Friendica;\r
+// src/BaseManager.php\r
+<?php\r
+namespace Friendica;\r
 \r
-       class BaseManager {\r
-               public function thatFunctionEveryManagerUses() { ... }\r
-       }\r
+class BaseManager {\r
+       public function thatFunctionEveryManagerUses() { ... }\r
+}\r
 ```\r
 \r
 and then let's change the ItemsManager class to use this code\r
 \r
 ```php\r
-       // src/ItemsManager.php\r
-       <?php\r
-       namespace \Friendica;\r
-\r
-       class ItemsManager extends BaseManager {\r
-               public function getAll() { ... }\r
-               public function getByID($id) { ... }\r
-       }\r
+// src/ItemsManager.php\r
+<?php\r
+namespace Friendica;\r
+\r
+class ItemsManager extends BaseManager {\r
+       public function getAll() { ... }\r
+       public function getByID($id) { ... }\r
+}\r
 ```\r
 \r
 Even though we didn't explicitly include the `src/BaseManager.php` file, the autoloader will when this class is first defined, because it is referenced as a parent class.\r
 It works with the "BaseManager" example here and it works when we need to call static methods:\r
 \r
 ```php\r
-       // src/Dfrn.php\r
-       <?php\r
-       namespace \Friendica;\r
+// src/Dfrn.php\r
+<?php\r
+namespace Friendica;\r
 \r
-       class Dfrn {\r
-               public static function  mail($item, $owner) { ... }\r
-       }\r
+class Dfrn {\r
+       public static function  mail($item, $owner) { ... }\r
+}\r
 ```\r
 \r
 ```php\r
-       // mod/mail.php\r
-       <?php\r
-\r
-       mail_post($a){\r
-               ...\r
-               \Friendica\dfrn::mail($item, $owner);\r
-               ...\r
-       }\r
+// mod/mail.php\r
+<?php\r
+\r
+mail_post($a){\r
+       ...\r
+       Friendica\dfrn::mail($item, $owner);\r
+       ...\r
+}\r
 ```\r
 \r
 If your code is in same namespace as the class you need, you don't need to prepend it:\r
 \r
 ```php\r
-       // include/delivery.php\r
-       <?php\r
-\r
-       namespace \Friendica;\r
-\r
-       // this is the same content of current include/delivery.php,\r
-       // but has been declared to be in "Friendica" namespace\r
-\r
-       [...]\r
-       switch($contact['network']) {\r
-               case NETWORK_DFRN:\r
-                       if ($mail) {\r
-                               $item['body'] = ...\r
-                               $atom = Dfrn::mail($item, $owner);\r
-                       } elseif ($fsuggest) {\r
-                               $atom = Dfrn::fsuggest($item, $owner);\r
-                               q("DELETE FROM `fsuggest` WHERE `id` = %d LIMIT 1", intval($item['id']));\r
-                       } elseif ($relocate)\r
-                               $atom = Dfrn::relocate($owner, $uid);\r
-       [...]\r
+// include/delivery.php\r
+<?php\r
+\r
+namespace Friendica;\r
+\r
+// this is the same content of current include/delivery.php,\r
+// but has been declared to be in "Friendica" namespace\r
+\r
+[...]\r
+switch($contact['network']) {\r
+       case NETWORK_DFRN:\r
+               if ($mail) {\r
+                       $item['body'] = ...\r
+                       $atom = Dfrn::mail($item, $owner);\r
+               } elseif ($fsuggest) {\r
+                       $atom = Dfrn::fsuggest($item, $owner);\r
+                       q("DELETE FROM `fsuggest` WHERE `id` = %d LIMIT 1", intval($item['id']));\r
+               } elseif ($relocate)\r
+                       $atom = Dfrn::relocate($owner, $uid);\r
+[...]\r
 ```\r
 \r
 This is the current code of `include/delivery.php`, and since the code is declared to be in the "Friendica" namespace, you don't need to write it when you need to use the "Dfrn" class.\r
 But if you want to use classes from another library, you need to use the full namespace, e.g.\r
 \r
 ```php\r
-       // src/Diaspora.php\r
-       <?php\r
+// src/Diaspora.php\r
+<?php\r
 \r
-       namespace \Friendica;\r
+namespace Friendica;\r
 \r
-       class Diaspora {\r
-               public function md2bbcode() {\r
-                       $html = \Michelf\MarkdownExtra::defaultTransform($text);\r
-               }\r
+class Diaspora {\r
+       public function md2bbcode() {\r
+               $html = \Michelf\MarkdownExtra::defaultTransform($text);\r
        }\r
+}\r
 ```\r
 \r
 if you use that class in many places of the code and you don't want to write the full path to the class every time, you can use the "use" PHP keyword\r
 \r
 ```php\r
-       // src/Diaspora.php\r
-       <?php\r
-       namespace \Friendica;\r
+// src/Diaspora.php\r
+<?php\r
+namespace Friendica;\r
 \r
-       use \Michelf\MarkdownExtra;\r
+use \Michelf\MarkdownExtra;\r
 \r
-       class Diaspora {\r
-               public function md2bbcode() {\r
-                       $html = MarkdownExtra::defaultTransform($text);\r
-               }\r
+class Diaspora {\r
+       public function md2bbcode() {\r
+               $html = MarkdownExtra::defaultTransform($text);\r
        }\r
+}\r
 ```\r
 \r
 Note that namespaces are like paths in filesystem, separated by "\", with the first "\" being the global scope.\r
 You can go deeper if you want to, like:\r
 \r
 ```\r
-       // src/Network/Dfrn.php\r
-    <?php\r
-    namespace \Friendica\Network;\r
+// src/Network/Dfrn.php\r
+<?php\r
+namespace Friendica\Network;\r
 \r
-    class Dfrn {\r
-    }\r
+class Dfrn {\r
+}\r
 ```\r
 \r
-Please note that the location of the file defining the class must be placed in the appropriate sub-folders of `src` if the namespace isn't plain `\Friendica`.\r
+Please note that the location of the file defining the class must be placed in the appropriate sub-folders of `src` if the namespace isn't plain `Friendica`.\r
 \r
 or\r
 \r
 ```\r
-       // src/Dba/Mysql\r
-    <?php\r
-    namespace \Friendica\Dba;\r
+// src/Dba/Mysql\r
+<?php\r
+namespace Friendica\Dba;\r
 \r
-    class Mysql {\r
-    }\r
+class Mysql {\r
+}\r
 ```\r
 \r
 So you can think of namespaces as folders in a Unix file system, with global scope as the root ("\").\r
+\r
+## Related\r
+\r
+* [Using Composer](help/Composer)\r
+* [How To Move Classes to `src`](help/Developer-How-To-Move-Classes-to-src)
\ No newline at end of file
index 61387753bfc206739e893aadcc3e697a86a12934..1d5c831ef45ba32dab6297d22fcac25e8d609207 100644 (file)
@@ -90,7 +90,7 @@ function help_content(App $a) {
                for($k=0;$k<$lastlevel; $k++) $toc.="</ul>";
                $html = implode("\n",$lines);
 
-               $a->page['aside'] = $toc.$a->page['aside'];
+               $a->page['aside'] = '<section class="help-aside-wrapper">' . $toc . $a->page['aside'] . '</section>';
        }
 
        $html = "
index 91b01e950a749179e38bb5974c568aae8468746a..01cab105bc4602d610923f2f6bffeede36188b1f 100644 (file)
@@ -98,7 +98,7 @@ blockquote {
 code {
     white-space: pre-wrap;
 }
-.help-content-wrapper code {display: inline}
+.help-content-wrapper code, .help-aside-wrapper code {display: inline}
 
 /*
 * standard page elements