]> git.mxchange.org Git - friendica.git/blobdiff - boot.php
Some more documentation - again.
[friendica.git] / boot.php
index ffbe34a8e0249a2e33e61400a5f442120340753e..a70c7bf616397e707f337095be8257b3534c88c8 100644 (file)
--- a/boot.php
+++ b/boot.php
@@ -17,6 +17,8 @@
  * easily as email does today.
  */
 
+require_once('include/autoloader.php');
 require_once('include/config.php');
 require_once('include/network.php');
 require_once('include/plugin.php');
@@ -28,7 +30,7 @@ require_once('include/cache.php');
 require_once('library/Mobile_Detect/Mobile_Detect.php');
 require_once('include/features.php');
 require_once('include/identity.php');
-
+require_once('include/pidfile.php');
 require_once('update.php');
 require_once('include/dbstructure.php');
 
@@ -36,14 +38,23 @@ define ( 'FRIENDICA_PLATFORM',     'Friendica');
 define ( 'FRIENDICA_CODENAME',     'Asparagus');
 define ( 'FRIENDICA_VERSION',      '3.5-dev' );
 define ( 'DFRN_PROTOCOL_VERSION',  '2.23'    );
-define ( 'DB_UPDATE_VERSION',      1191      );
+define ( 'DB_UPDATE_VERSION',      1194      );
+
+/**
+ * @brief Constant with a HTML line break.
+ *
+ * Contains a HTML line break (br) element and a real carriage return with line
+ * feed for the source.
+ * This can be used in HTML and JavaScript where needed a line break.
+ */
 define ( 'EOL',                    "<br />\r\n"     );
 define ( 'ATOM_TIME',              'Y-m-d\TH:i:s\Z' );
 
 
 /**
- *
- * Image storage quality. Lower numbers save space at cost of image detail.
+ * @brief Image storage quality.
+ * 
+ * Lower numbers save space at cost of image detail.
  * For ease of upgrade, please do not change here. Change jpeg quality with
  * $a->config['system']['jpeg_quality'] = n;
  * in .htconfig.php, where n is netween 1 and 100, and with very poor results
@@ -83,61 +94,76 @@ define ( 'MAX_IMAGE_LENGTH',        -1  );
 define ( 'DEFAULT_DB_ENGINE',  'MyISAM'  );
 
 /**
+ * @name SSL Policy
+ * 
  * SSL redirection policies
+ * @{
  */
-
 define ( 'SSL_POLICY_NONE',         0 );
 define ( 'SSL_POLICY_FULL',         1 );
 define ( 'SSL_POLICY_SELFSIGN',     2 );
-
+/* @}*/
 
 /**
+ * @name Logger
+ * 
  * log levels
+ * @{
  */
-
 define ( 'LOGGER_NORMAL',          0 );
 define ( 'LOGGER_TRACE',           1 );
 define ( 'LOGGER_DEBUG',           2 );
 define ( 'LOGGER_DATA',            3 );
 define ( 'LOGGER_ALL',             4 );
+/* @}*/
 
 /**
- * cache levels
+ * @name Cache
+ * 
+ * Cache levels
+ * @{
  */
-
 define ( 'CACHE_MONTH',            0 );
 define ( 'CACHE_WEEK',             1 );
 define ( 'CACHE_DAY',              2 );
 define ( 'CACHE_HOUR',             3 );
+/* @}*/
 
 /**
- * registration policies
+ * @name Register
+ * 
+ * Registration policies
+ * @{
  */
-
 define ( 'REGISTER_CLOSED',        0 );
 define ( 'REGISTER_APPROVE',       1 );
 define ( 'REGISTER_OPEN',          2 );
+/** @}*/
 
 /**
- * relationship types
+ * @name Contact_is
+ * 
+ * Relationship types
+ * @{
  */
-
 define ( 'CONTACT_IS_FOLLOWER', 1);
 define ( 'CONTACT_IS_SHARING',  2);
 define ( 'CONTACT_IS_FRIEND',   3);
-
+/** @}*/
 
 /**
+ * @name Update
+ * 
  * DB update return values
+ * @{
  */
-
 define ( 'UPDATE_SUCCESS', 0);
 define ( 'UPDATE_FAILED',  1);
+/** @}*/
 
 
 /**
- *
- * page/profile types
+ * @name page/profile types
  *
  * PAGE_NORMAL is a typical personal profile account
  * PAGE_SOAPBOX automatically approves all friend requests as CONTACT_IS_SHARING, (readonly)
@@ -145,24 +171,33 @@ define ( 'UPDATE_FAILED',  1);
  *      write access to wall and comments (no email and not included in page owner's ACL lists)
  * PAGE_FREELOVE automatically approves all friend requests as full friends (CONTACT_IS_FRIEND).
  *
+ * @{
  */
-
 define ( 'PAGE_NORMAL',            0 );
 define ( 'PAGE_SOAPBOX',           1 );
 define ( 'PAGE_COMMUNITY',         2 );
 define ( 'PAGE_FREELOVE',          3 );
 define ( 'PAGE_BLOG',              4 );
 define ( 'PAGE_PRVGROUP',          5 );
+/** @}*/
 
-// Type of the community page
+/**
+ * @name CP
+ * 
+ * Type of the community page
+ * @{
+ */
 define ( 'CP_NO_COMMUNITY_PAGE',   -1 );
 define ( 'CP_USERS_ON_SERVER',     0 );
 define ( 'CP_GLOBAL_COMMUNITY',    1 );
+/** @}*/
 
 /**
+ * @name Network
+ * 
  * Network and protocol family types
+ * @{
  */
-
 define ( 'NETWORK_DFRN',             'dfrn');    // Friendica, Mistpark, other DFRN implementations
 define ( 'NETWORK_ZOT',              'zot!');    // Zot!
 define ( 'NETWORK_OSTATUS',          'stat');    // status.net, identi.ca, GNU-social, other OStatus implementations
@@ -183,6 +218,7 @@ define ( 'NETWORK_APPNET',           'apdn');    // app.net
 define ( 'NETWORK_NEWS',             'nntp');    // Network News Transfer Protocol
 define ( 'NETWORK_ICALENDAR',        'ical');    // iCalendar
 define ( 'NETWORK_PHANTOM',          'unkn');    // Place holder
+/** @}*/
 
 /**
  * These numbers are used in stored permissions
@@ -229,9 +265,11 @@ define ( 'ZCURL_TIMEOUT' , (-1));
 
 
 /**
- * email notification options
+ * @name Notify
+ * 
+ * Email notification options
+ * @{
  */
-
 define ( 'NOTIFY_INTRO',    0x0001 );
 define ( 'NOTIFY_CONFIRM',  0x0002 );
 define ( 'NOTIFY_WALL',     0x0004 );
@@ -245,12 +283,15 @@ define ( 'NOTIFY_POKE',     0x0200 );
 define ( 'NOTIFY_SHARE',    0x0400 );
 
 define ( 'NOTIFY_SYSTEM',   0x8000 );
+/* @}*/
 
 
 /**
+ * @name Term
+ * 
  * Tag/term types
+ * @{
  */
-
 define ( 'TERM_UNKNOWN',   0 );
 define ( 'TERM_HASHTAG',   1 );
 define ( 'TERM_MENTION',   2 );
@@ -266,9 +307,11 @@ define ( 'TERM_OBJ_PHOTO', 2 );
 
 
 /**
- * various namespaces we may need to parse
+ * @name Namespaces
+ * 
+ * Various namespaces we may need to parse
+ * @{
  */
-
 define ( 'NAMESPACE_ZOT',             'http://purl.org/zot' );
 define ( 'NAMESPACE_DFRN' ,           'http://purl.org/macgirvin/dfrn/1.0' );
 define ( 'NAMESPACE_THREAD' ,         'http://purl.org/syndication/thread/1.0' );
@@ -284,10 +327,14 @@ define ( 'NAMESPACE_FEED',            'http://schemas.google.com/g/2010#updates-
 define ( 'NAMESPACE_OSTATUS',         'http://ostatus.org/schema/1.0' );
 define ( 'NAMESPACE_STATUSNET',       'http://status.net/schema/api/1/' );
 define ( 'NAMESPACE_ATOM1',           'http://www.w3.org/2005/Atom' );
+/* @}*/
+
 /**
- * activity stream defines
+ * @name Activity
+ * 
+ * Activity stream defines
+ * @{
  */
-
 define ( 'ACTIVITY_LIKE',        NAMESPACE_ACTIVITY_SCHEMA . 'like' );
 define ( 'ACTIVITY_DISLIKE',     NAMESPACE_DFRN            . '/dislike' );
 define ( 'ACTIVITY_ATTEND',      NAMESPACE_ZOT             . '/activity/attendyes' );
@@ -326,14 +373,19 @@ define ( 'ACTIVITY_OBJ_GROUP',   NAMESPACE_ACTIVITY_SCHEMA . 'group' );
 define ( 'ACTIVITY_OBJ_TAGTERM', NAMESPACE_DFRN            . '/tagterm' );
 define ( 'ACTIVITY_OBJ_PROFILE', NAMESPACE_DFRN            . '/profile' );
 define ( 'ACTIVITY_OBJ_QUESTION', 'http://activityschema.org/object/question' );
+/* @}*/
 
 /**
- * item weight for query ordering
+ * @name Gravity
+ * 
+ * Item weight for query ordering
+ * @{
  */
-
 define ( 'GRAVITY_PARENT',       0);
 define ( 'GRAVITY_LIKE',         3);
 define ( 'GRAVITY_COMMENT',      6);
+/* @}*/
+
 
 /**
  *
@@ -413,10 +465,12 @@ class App {
        public  $plugins;
        public  $apps = array();
        public  $identities;
-       public  $is_mobile;
-       public  $is_tablet;
+       public  $is_mobile = false;
+       public  $is_tablet = false;
        public  $is_friendica_app;
        public  $performance = array();
+       public  $callstack = array();
+       public  $theme_info = array();
 
        public $nav_sel;
 
@@ -479,8 +533,10 @@ class App {
        private $cached_profile_image;
        private $cached_profile_picdate;
 
+       private static $a;
+
        /**
-        * App constructor.
+        * @brief App constructor.
         */
        function __construct() {
 
@@ -504,6 +560,12 @@ class App {
                $this->performance["marktime"] = 0;
                $this->performance["markstart"] = microtime(true);
 
+               $this->callstack["database"] = array();
+               $this->callstack["network"] = array();
+               $this->callstack["file"] = array();
+               $this->callstack["rendering"] = array();
+               $this->callstack["parser"] = array();
+
                $this->config = array();
                $this->page = array();
                $this->pager= array();
@@ -529,18 +591,9 @@ class App {
                if(x($_SERVER,'SERVER_NAME')) {
                        $this->hostname = $_SERVER['SERVER_NAME'];
 
-                       // See bug 437 - this didn't work so disabling it
-                       //if(stristr($this->hostname,'xn--')) {
-                               // PHP or webserver may have converted idn to punycode, so
-                               // convert punycode back to utf-8
-                       //      require_once('library/simplepie/idn/idna_convert.class.php');
-                       //      $x = new idna_convert();
-                       //      $this->hostname = $x->decode($_SERVER['SERVER_NAME']);
-                       //}
-
                        if(x($_SERVER,'SERVER_PORT') && $_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443)
                                $this->hostname .= ':' . $_SERVER['SERVER_PORT'];
-                       /**
+                       /*
                         * Figure out if we are running at the top of a domain
                         * or in a sub-directory and adjust accordingly
                         */
@@ -593,7 +646,7 @@ class App {
                        $this->cmd = 'profile/' . substr($this->cmd,2);
 
 
-               /**
+               /*
                 *
                 * Break the URL path into C style argc/argv style arguments for our
                 * modules. Given "http://example.com/module/arg1/arg2", $this->argc
@@ -620,7 +673,7 @@ class App {
                        $this->module = 'home';
                }
 
-               /**
+               /*
                 * See if there is any page number information, and initialise
                 * pagination
                 */
@@ -632,7 +685,7 @@ class App {
                        $this->pager['start'] = 0;
                $this->pager['total'] = 0;
 
-               /**
+               /*
                 * Detect mobile devices
                 */
 
@@ -643,7 +696,7 @@ class App {
                // Friendica-Client
                $this->is_friendica_app = ($_SERVER['HTTP_USER_AGENT'] == "Apache-HttpClient/UNAVAILABLE (java 1.4)");
 
-               /**
+               /*
                 * register template engines
                 */
                $dc = get_declared_classes();
@@ -653,6 +706,8 @@ class App {
                        }
                }
 
+               self::$a = $this;
+
        }
 
        function get_basepath() {
@@ -677,6 +732,10 @@ class App {
 
        function get_baseurl($ssl = false) {
 
+               // Is the function called statically?
+               if (!is_object($this))
+                       return(self::$a->get_baseurl($ssl));
+
                $scheme = $this->scheme;
 
                if((x($this->config,'system')) && (x($this->config['system'],'ssl_policy'))) {
@@ -797,11 +856,11 @@ class App {
 
                $shortcut_icon = get_config("system", "shortcut_icon");
                if ($shortcut_icon == "")
-                       $shortcut_icon = $this->get_baseurl()."/images/friendica-32.png";
+                       $shortcut_icon = "images/friendica-32.png";
 
                $touch_icon = get_config("system", "touch_icon");
                if ($touch_icon == "")
-                       $touch_icon = $this->get_baseurl()."/images/friendica-128.png";
+                       $touch_icon = "images/friendica-128.png";
 
                $tpl = get_markup_template('head.tpl');
                $this->page['htmlhead'] = replace_macros($tpl,array(
@@ -853,6 +912,10 @@ class App {
        }
 
        function get_cached_avatar_image($avatar_image){
+               return $avatar_image;
+
+               // The following code is deactivated. It doesn't seem to make any sense and it slows down the system.
+               /*
                if($this->cached_profile_image[$avatar_image])
                        return $this->cached_profile_image[$avatar_image];
 
@@ -872,9 +935,29 @@ class App {
                        }
                }
                return $this->cached_profile_image[$avatar_image];
+               */
        }
 
 
+       /**
+        * @brief Removes the baseurl from an url. This avoids some mixed content problems.
+        *
+        * @param string $url
+        *
+        * @return string The cleaned url
+        */
+       function remove_baseurl($url){
+
+               // Is the function called statically?
+               if (!is_object($this))
+                       return(self::$a->remove_baseurl($url));
+
+               $url = normalise_link($url);
+               $base = normalise_link($this->get_baseurl());
+               $url = str_replace($base."/", "", $url);
+               return $url;
+       }
+
        /**
         * @brief Register template engine class
         * 
@@ -964,8 +1047,42 @@ class App {
        function save_timestamp($stamp, $value) {
                $duration = (float)(microtime(true)-$stamp);
 
+               if (!isset($this->performance[$value])) {
+                       // Prevent ugly E_NOTICE
+                       $this->performance[$value] = 0;
+               }
+
                $this->performance[$value] += (float)$duration;
                $this->performance["marktime"] += (float)$duration;
+
+               $callstack = $this->callstack();
+
+               if (!isset($this->callstack[$value][$callstack])) {
+                       // Prevent ugly E_NOTICE
+                       $this->callstack[$value][$callstack] = 0;
+               }
+
+               $this->callstack[$value][$callstack] += (float)$duration;
+
+       }
+
+       /**
+        * @brief Returns a string with a callstack. Can be used for logging.
+        *
+        * @return string
+        */
+       function callstack() {
+               $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 6);
+
+               // We remove the first two items from the list since they contain data that we don't need.
+               array_shift($trace);
+               array_shift($trace);
+
+               $callstack = array();
+               foreach ($trace AS $func)
+                       $callstack[] = $func["function"];
+
+               return implode(", ", $callstack);
        }
 
        function mark_timestamp($mark) {
@@ -981,6 +1098,55 @@ class App {
                return($this->is_friendica_app);
        }
 
+       /**
+        * @brief Checks if the maximum load is reached
+        *
+        * @return bool Is the load reached?
+        */
+       function maxload_reached() {
+
+               $maxsysload = intval(get_config('system', 'maxloadavg'));
+               if ($maxsysload < 1)
+                       $maxsysload = 50;
+
+               $load = current_load();
+               if ($load) {
+                       if (intval($load) > $maxsysload) {
+                               logger('system: load '.$load.' too high.');
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * @brief Checks if the process is already running
+        *
+        * @param string $taskname The name of the task that will be used for the name of the lockfile
+        * @param string $task The path and name of the php script
+        * @param int $timeout The timeout after which a task should be killed
+        *
+        * @return bool Is the process running?
+        */
+       function is_already_running($taskname, $task = "", $timeout = 540) {
+
+               $lockpath = get_lockpath();
+               if ($lockpath != '') {
+                       $pidfile = new pidfile($lockpath, $taskname);
+                       if ($pidfile->is_already_running()) {
+                               logger("Already running");
+                               if ($pidfile->running_time() > $timeout) {
+                                       $pidfile->kill();
+                                       logger("killed stale process");
+                                       // Calling a new instance
+                                       if ($task != "")
+                                               proc_run('php', $task);
+                               }
+                               return true;
+                       }
+               }
+               return false;
+       }
 }
 
 /**
@@ -1229,22 +1395,21 @@ function run_update_function($x) {
        return true;
 }
 
-
-function check_plugins(&$a) {
-
-       /**
-        *
-        * Synchronise plugins:
-        *
-        * $a->config['system']['addon'] contains a comma-separated list of names
-        * of plugins/addons which are used on this system.
-        * Go through the database list of already installed addons, and if we have
-        * an entry, but it isn't in the config list, call the uninstall procedure
-        * and mark it uninstalled in the database (for now we'll remove it).
-        * Then go through the config list and if we have a plugin that isn't installed,
-        * call the install procedure and add it to the database.
-        *
+/**
+ * @brief Synchronise plugins:
+ *
+ * $a->config['system']['addon'] contains a comma-separated list of names
+ * of plugins/addons which are used on this system.
+ * Go through the database list of already installed addons, and if we have
+ * an entry, but it isn't in the config list, call the uninstall procedure
+ * and mark it uninstalled in the database (for now we'll remove it).
+ * Then go through the config list and if we have a plugin that isn't installed,
+ * call the install procedure and add it to the database.
+ * 
+ * @param App $a
+ *
         */
+function check_plugins(&$a) {
 
        $r = q("SELECT * FROM `addon` WHERE `installed` = 1");
        if(count($r))
@@ -1301,7 +1466,7 @@ function get_guid($size=16, $prefix = "") {
                $prefix = substr($prefix, 0, $size - 22);
                return(str_replace(".", "", uniqid($prefix, true)));
        } else {
-               $prefix = substr($prefix, 0, $size - 13);
+               $prefix = substr($prefix, 0, max($size - 13, 0));
                return(uniqid($prefix));
        }
 }
@@ -1316,6 +1481,9 @@ function get_guid($size=16, $prefix = "") {
  * 
  * @return string
  *     Returns the complete html for inserting into the page
+ * 
+ * @hooks 'login_hook'
+ *     string $o
  */
 function login($register = false, $hiddens=false) {
        $a = get_app();
@@ -1330,7 +1498,7 @@ function login($register = false, $hiddens=false) {
 
        $noid = get_config('system','no_openid');
 
-       $dest_url = $a->get_baseurl(true) . '/' . $a->query_string;
+       $dest_url = $a->query_string;
 
        if(local_user()) {
                $tpl = get_markup_template("logout.tpl");
@@ -1390,6 +1558,9 @@ function killme() {
  * @brief Redirect to another URL and terminate this process.
  */
 function goaway($s) {
+       if (!strstr(normalise_link($s), "http://"))
+               $s = App::get_baseurl()."/".$s;
+
        header("Location: $s");
        killme();
 }
@@ -1461,17 +1632,18 @@ function get_max_import_size() {
 }
 
 /**
+ * @brief Wrap calls to proc_close(proc_open()) and call hook
+ *     so plugins can take part in process :)
  *
- * Wrap calls to proc_close(proc_open()) and call hook
- * so plugins can take part in process :)
- *
- * args:
- * $cmd program to run
- *  next args are passed as $cmd command line
- *
+ * @param string $cmd program to run
+ * 
+ * next args are passed as $cmd command line
  * e.g.: proc_run("ls","-la","/tmp");
  *
- * $cmd and string args are surrounded with ""
+ * @note $cmd and string args are surrounded with ""
+ * 
+ * @hooks 'proc_run'
+ *     array $arr
  */
 function proc_run($cmd){
 
@@ -1648,9 +1820,9 @@ function current_theme_url() {
 
        $opts = (($a->profile_uid) ? '?f=&puid=' . $a->profile_uid : '');
        if (file_exists('view/theme/' . $t . '/style.php'))
-               return($a->get_baseurl() . '/view/theme/' . $t . '/style.pcss' . $opts);
+               return('view/theme/'.$t.'/style.pcss'.$opts);
 
-       return($a->get_baseurl() . '/view/theme/' . $t . '/style.css');
+       return('view/theme/'.$t.'/style.css');
 }
 
 function feed_birthday($uid,$tz) {
@@ -1955,8 +2127,8 @@ function get_temppath() {
 }
 
 function set_template_engine(&$a, $engine = 'internal') {
-// This function is no longer necessary, but keep it as a wrapper to the class method
-// to avoid breaking themes again unnecessarily
+/// @note This function is no longer necessary, but keep it as a wrapper to the class method
+/// to avoid breaking themes again unnecessarily
 
        $a->set_template_engine($engine);
 }
@@ -2007,3 +2179,25 @@ function current_load() {
 
        return max($load_arr);
 }
+
+/**
+ * @brief get c-style args
+ * 
+ * @return int
+ */
+function argc() {
+       return get_app()->argc;
+}
+
+/**
+ * @brief Returns the value of a argv key
+ * 
+ * @param int $x argv key
+ * @return string Value of the argv key
+ */
+function argv($x) {
+       if(array_key_exists($x,get_app()->argv))
+               return get_app()->argv[$x];
+
+       return '';
+}