]> git.mxchange.org Git - friendica.git/blobdiff - mod/admin.php
Merge pull request #2902 from tobiasd/20161110-lng
[friendica.git] / mod / admin.php
index a98f464f813d30b36b446ddffae0fc1cca47501c..287eff27258c41ef278811c8cc486e5a7da74b84 100644 (file)
@@ -165,7 +165,7 @@ function admin_content(&$a) {
 
        /* get plugins admin page */
 
-       $r = q("SELECT `name` FROM `addon` WHERE `plugin_admin`=1 ORDER BY `name`");
+       $r = q("SELECT `name` FROM `addon` WHERE `plugin_admin` = 1 ORDER BY `name`");
        $aside_tools['plugins_admin']=array();
        foreach ($r as $h){
                $plugin =$h['name'];
@@ -271,7 +271,7 @@ function admin_page_federation(&$a) {
        // displayed on the stats page.
        $platforms = array('Friendica', 'Diaspora', '%%red%%', 'Hubzilla', 'GNU Social', 'StatusNet');
        $colors    = array('Friendica' => '#ffc018',     // orange from the logo
-                          'Diaspora'  => '#a1a1a1',     // logo is black and white, makes a gray
+                           'Diaspora'  => '#a1a1a1',     // logo is black and white, makes a gray
                           '%%red%%'   => '#c50001',     // fire red from the logo
                           'Hubzilla'  => '#43488a',     // blue from the logo
                           'GNU Social'=> '#a22430',     // dark red from the logo
@@ -282,17 +282,17 @@ function admin_page_federation(&$a) {
        foreach ($platforms as $p) {
                // get a total count for the platform, the name and version of the
                // highest version and the protocol tpe
-               $c = q('SELECT count(*) AS total, platform, network, version FROM gserver
-                       WHERE platform LIKE "%s" AND last_contact > last_failure AND `version` != ""
-                       ORDER BY version ASC;', $p);
+               $c = qu('SELECT COUNT(*) AS `total`, `platform`, `network`, `version` FROM `gserver`
+                               WHERE `platform` LIKE "%s" AND `last_contact` > `last_failure` AND `version` != ""
+                               ORDER BY `version` ASC;', $p);
                $total = $total + $c[0]['total'];
 
                // what versions for that platform do we know at all?
                // again only the active nodes
-               $v = q('SELECT count(*) AS total, version FROM gserver
-                       WHERE last_contact > last_failure AND platform LIKE "%s"  AND `version` != ""
-                       GROUP BY version
-                       ORDER BY version;', $p);
+               $v = qu('SELECT COUNT(*) AS `total`, `version` FROM `gserver`
+                               WHERE `last_contact` > `last_failure` AND `platform` LIKE "%s"  AND `version` != ""
+                               GROUP BY `version`
+                               ORDER BY `version`;', $p);
 
                //
                // clean up version numbers
@@ -386,7 +386,10 @@ function admin_page_federation(&$a) {
  */
 function admin_page_queue(&$a) {
        // get content from the queue table
-       $r = q("SELECT c.name,c.nurl,q.id,q.network,q.created,q.last from queue as q, contact as c where c.id=q.cid order by q.cid, q.created;");
+       $r = q("SELECT `c`.`name`, `c`.`nurl`, `q`.`id`, `q`.`network`, `q`.`created`, `q`.`last`
+                       FROM `queue` AS `q`, `contact` AS `c`
+                       WHERE `c`.`id` = `q`.`cid`
+                       ORDER BY `q`.`cid`, `q`.`created`;");
 
        $t = get_markup_template("admin_queue.tpl");
        return replace_macros($t, array(
@@ -416,7 +419,7 @@ function admin_page_queue(&$a) {
  * @return string
  */
 function admin_page_summary(&$a) {
-       $r = q("SELECT `page-flags`, COUNT(uid) as `count` FROM `user` GROUP BY `page-flags`");
+       $r = q("SELECT `page-flags`, COUNT(`uid`) AS `count` FROM `user` GROUP BY `page-flags`");
        $accounts = array(
                array(t('Normal Account'), 0),
                array(t('Soapbox Account'), 0),
@@ -431,18 +434,25 @@ function admin_page_summary(&$a) {
 
        logger('accounts: '.print_r($accounts,true),LOGGER_DATA);
 
-       $r = q("SELECT COUNT(id) as `count` FROM `register`");
+       $r = qu("SELECT COUNT(`id`) AS `count` FROM `register`");
        $pending = $r[0]['count'];
 
-       $r = q("select count(*) as total from deliverq where 1");
+       $r = qu("SELECT COUNT(*) AS `total` FROM `deliverq` WHERE 1");
        $deliverq = (($r) ? $r[0]['total'] : 0);
 
-       $r = q("select count(*) as total from queue where 1");
+       $r = qu("SELECT COUNT(*) AS `total` FROM `queue` WHERE 1");
        $queue = (($r) ? $r[0]['total'] : 0);
 
+       if (get_config('system','worker')) {
+               $r = qu("SELECT COUNT(*) AS `total` FROM `workerqueue` WHERE 1");
+               $workerqueue = (($r) ? $r[0]['total'] : 0);
+       } else {
+               $workerqueue = 0;
+       }
+
        // We can do better, but this is a quick queue status
 
-       $queues = array('label' => t('Message queues'), 'deliverq' => $deliverq, 'queue' => $queue);
+       $queues = array('label' => t('Message queues'), 'deliverq' => $deliverq, 'queue' => $queue, 'workerq' => $workerqueue);
 
 
        $t = get_markup_template("admin_summary.tpl");
@@ -450,6 +460,7 @@ function admin_page_summary(&$a) {
                '$title' => t('Administration'),
                '$page' => t('Summary'),
                '$queues' => $queues,
+               '$workeractive' => get_config('system','worker'),
                '$users' => array(t('Registered users'), $users),
                '$accounts' => $accounts,
                '$pending' => array(t('Pending registrations'), $pending),
@@ -492,6 +503,10 @@ function admin_page_site_post(&$a) {
 
                $old_url = $a->get_baseurl(true);
 
+               // Generate host names for relocation the addresses in the format user@address.tld
+               $new_host = str_replace("http://", "@", normalise_link($new_url));
+               $old_host = str_replace("http://", "@", normalise_link($old_url));
+
                function update_table($table_name, $fields, $old_url, $new_url) {
                        global $db, $a;
 
@@ -516,21 +531,26 @@ function admin_page_site_post(&$a) {
                }
 
                // update tables
+               // update profile links in the format "http://server.tld"
                update_table("profile", array('photo', 'thumb'), $old_url, $new_url);
                update_table("term", array('url'), $old_url, $new_url);
-               update_table("contact", array('photo','thumb','micro','url','nurl','request','notify','poll','confirm','poco'), $old_url, $new_url);
-               update_table("gcontact", array('photo','url','nurl','server_url'), $old_url, $new_url);
-               update_table("item", array('owner-link','owner-avatar','author-name','author-link','author-avatar','body','plink','tag'), $old_url, $new_url);
+               update_table("contact", array('photo','thumb','micro','url','nurl','alias','request','notify','poll','confirm','poco', 'avatar'), $old_url, $new_url);
+               update_table("gcontact", array('url','nurl','photo','server_url','notify','alias'), $old_url, $new_url);
+               update_table("item", array('owner-link','owner-avatar','author-link','author-avatar','body','plink','tag'), $old_url, $new_url);
+
+               // update profile addresses in the format "user@server.tld"
+               update_table("contact", array('addr'), $old_host, $new_host);
+               update_table("gcontact", array('connect','addr'), $old_host, $new_host);
 
                // update config
                $a->set_baseurl($new_url);
                set_config('system','url',$new_url);
 
                // send relocate
-               $users = q("SELECT uid FROM user WHERE account_removed = 0 AND account_expired = 0");
+               $users = q("SELECT `uid` FROM `user` WHERE `account_removed` = 0 AND `account_expired` = 0");
 
                foreach ($users as $user) {
-                       proc_run('php', 'include/notifier.php', 'relocate', $user['uid']);
+                       proc_run(PRIORITY_HIGH, 'include/notifier.php', 'relocate', $user['uid']);
                }
 
                info("Relocation started. Could take a while to complete.");
@@ -542,10 +562,10 @@ function admin_page_site_post(&$a) {
        $sitename               =       ((x($_POST,'sitename'))                 ? notags(trim($_POST['sitename']))              : '');
        $hostname               =       ((x($_POST,'hostname'))                 ? notags(trim($_POST['hostname']))              : '');
        $sender_email           =       ((x($_POST,'sender_email'))             ? notags(trim($_POST['sender_email']))          : '');
-       $banner                 =       ((x($_POST,'banner'))                   ? trim($_POST['banner'])                        : false);
+       $banner                 =       ((x($_POST,'banner'))                   ? trim($_POST['banner'])                        : false);
        $shortcut_icon          =       ((x($_POST,'shortcut_icon'))            ? notags(trim($_POST['shortcut_icon']))         : '');
        $touch_icon             =       ((x($_POST,'touch_icon'))               ? notags(trim($_POST['touch_icon']))            : '');
-       $info                   =       ((x($_POST,'info'))                     ? trim($_POST['info'])                          : false);
+       $info                   =       ((x($_POST,'info'))                     ? trim($_POST['info'])                          : false);
        $language               =       ((x($_POST,'language'))                 ? notags(trim($_POST['language']))              : '');
        $theme                  =       ((x($_POST,'theme'))                    ? notags(trim($_POST['theme']))                 : '');
        $theme_mobile           =       ((x($_POST,'theme_mobile'))             ? notags(trim($_POST['theme_mobile']))          : '');
@@ -598,6 +618,7 @@ function admin_page_site_post(&$a) {
        $dfrn_only              =       ((x($_POST,'dfrn_only'))                ? True                                          : False);
        $ostatus_disabled       =       !((x($_POST,'ostatus_disabled'))        ? True                                          : False);
        $ostatus_poll_interval  =       ((x($_POST,'ostatus_poll_interval'))    ? intval(trim($_POST['ostatus_poll_interval'])) :  0);
+       $ostatus_full_threads   =       ((x($_POST,'ostatus_full_threads'))     ? True                                          : False);
        $diaspora_enabled       =       ((x($_POST,'diaspora_enabled'))         ? True                                          : False);
        $ssl_policy             =       ((x($_POST,'ssl_policy'))               ? intval($_POST['ssl_policy'])                  : 0);
        $force_ssl              =       ((x($_POST,'force_ssl'))                ? True                                          : False);
@@ -618,6 +639,10 @@ function admin_page_site_post(&$a) {
        $only_tag_search        =       ((x($_POST,'only_tag_search'))          ? True                                          : False);
        $rino                   =       ((x($_POST,'rino'))                     ? intval($_POST['rino'])                        : 0);
        $embedly                =       ((x($_POST,'embedly'))                  ? notags(trim($_POST['embedly']))               : '');
+       $worker                 =       ((x($_POST,'worker'))                   ? True                                          : False);
+       $worker_queues          =       ((x($_POST,'worker_queues'))            ? intval($_POST['worker_queues'])               : 4);
+       $worker_dont_fork       =       ((x($_POST,'worker_dont_fork'))         ? True                                          : False);
+       $worker_fastlane        =       ((x($_POST,'worker_fastlane'))          ? True                                          : False);
 
        if($a->get_path() != "")
                $diaspora_enabled = false;
@@ -627,41 +652,41 @@ function admin_page_site_post(&$a) {
 
        if($ssl_policy != intval(get_config('system','ssl_policy'))) {
                if($ssl_policy == SSL_POLICY_FULL) {
-                       q("update `contact` set
-                               `url`     = replace(`url`    , 'http:' , 'https:'),
-                               `photo`   = replace(`photo`  , 'http:' , 'https:'),
-                               `thumb`   = replace(`thumb`  , 'http:' , 'https:'),
-                               `micro`   = replace(`micro`  , 'http:' , 'https:'),
-                               `request` = replace(`request`, 'http:' , 'https:'),
-                               `notify`  = replace(`notify` , 'http:' , 'https:'),
-                               `poll`    = replace(`poll`   , 'http:' , 'https:'),
-                               `confirm` = replace(`confirm`, 'http:' , 'https:'),
-                               `poco`    = replace(`poco`   , 'http:' , 'https:')
-                               where `self` = 1"
+                       q("UPDATE `contact` SET
+                               `url`     = REPLACE(`url`    , 'http:' , 'https:'),
+                               `photo`   = REPLACE(`photo`  , 'http:' , 'https:'),
+                               `thumb`   = REPLACE(`thumb`  , 'http:' , 'https:'),
+                               `micro`   = REPLACE(`micro`  , 'http:' , 'https:'),
+                               `request` = REPLACE(`request`, 'http:' , 'https:'),
+                               `notify`  = REPLACE(`notify` , 'http:' , 'https:'),
+                               `poll`    = REPLACE(`poll`   , 'http:' , 'https:'),
+                               `confirm` = REPLACE(`confirm`, 'http:' , 'https:'),
+                               `poco`    = REPLACE(`poco`   , 'http:' , 'https:')
+                               WHERE `self` = 1"
                        );
-                       q("update `profile` set
-                               `photo`   = replace(`photo`  , 'http:' , 'https:'),
-                               `thumb`   = replace(`thumb`  , 'http:' , 'https:')
-                               where 1 "
+                       q("UPDATE `profile` SET
+                               `photo`   = REPLACE(`photo`  , 'http:' , 'https:'),
+                               `thumb`   = REPLACE(`thumb`  , 'http:' , 'https:')
+                               WHERE 1 "
                        );
                }
                elseif($ssl_policy == SSL_POLICY_SELFSIGN) {
-                       q("update `contact` set
-                               `url`     = replace(`url`    , 'https:' , 'http:'),
-                               `photo`   = replace(`photo`  , 'https:' , 'http:'),
-                               `thumb`   = replace(`thumb`  , 'https:' , 'http:'),
-                               `micro`   = replace(`micro`  , 'https:' , 'http:'),
-                               `request` = replace(`request`, 'https:' , 'http:'),
-                               `notify`  = replace(`notify` , 'https:' , 'http:'),
-                               `poll`    = replace(`poll`   , 'https:' , 'http:'),
-                               `confirm` = replace(`confirm`, 'https:' , 'http:'),
-                               `poco`    = replace(`poco`   , 'https:' , 'http:')
-                               where `self` = 1"
+                       q("UPDATE `contact` SET
+                               `url`     = REPLACE(`url`    , 'https:' , 'http:'),
+                               `photo`   = REPLACE(`photo`  , 'https:' , 'http:'),
+                               `thumb`   = REPLACE(`thumb`  , 'https:' , 'http:'),
+                               `micro`   = REPLACE(`micro`  , 'https:' , 'http:'),
+                               `request` = REPLACE(`request`, 'https:' , 'http:'),
+                               `notify`  = REPLACE(`notify` , 'https:' , 'http:'),
+                               `poll`    = REPLACE(`poll`   , 'https:' , 'http:'),
+                               `confirm` = REPLACE(`confirm`, 'https:' , 'http:'),
+                               `poco`    = REPLACE(`poco`   , 'https:' , 'http:')
+                               WHERE `self` = 1"
                        );
-                       q("update `profile` set
-                               `photo`   = replace(`photo`  , 'https:' , 'http:'),
-                               `thumb`   = replace(`thumb`  , 'https:' , 'http:')
-                               where 1 "
+                       q("UPDATE `profile` SET
+                               `photo`   = REPLACE(`photo`  , 'https:' , 'http:'),
+                               `thumb`   = REPLACE(`thumb`  , 'https:' , 'http:')
+                               WHERE 1 "
                        );
                }
        }
@@ -746,6 +771,7 @@ function admin_page_site_post(&$a) {
        set_config('system','dfrn_only', $dfrn_only);
        set_config('system','ostatus_disabled', $ostatus_disabled);
        set_config('system','ostatus_poll_interval', $ostatus_poll_interval);
+       set_config('system','ostatus_full_threads', $ostatus_full_threads);
        set_config('system','diaspora_enabled', $diaspora_enabled);
 
        set_config('config','private_addons', $private_addons);
@@ -763,7 +789,10 @@ function admin_page_site_post(&$a) {
        set_config('system','proxy_disabled', $proxy_disabled);
        set_config('system','old_pager', $old_pager);
        set_config('system','only_tag_search', $only_tag_search);
-
+       set_config('system','worker', $worker);
+       set_config('system','worker_queues', $worker_queues);
+       set_config('system','worker_dont_fork', $worker_dont_fork);
+       set_config('system','worker_fastlane', $worker_fastlane);
 
        if($rino==2 and !function_exists('mcrypt_create_iv')) {
                notice(t("RINO2 needs mcrypt php extension to work."));
@@ -791,7 +820,7 @@ function admin_page_site_post(&$a) {
 function admin_page_site(&$a) {
 
        /* Installed langs */
-       $lang_choices = get_avaiable_languages();
+       $lang_choices = get_available_languages();
 
        if(strlen(get_config('system','directory_submit_url')) AND
                !strlen(get_config('system','directory'))) {
@@ -853,7 +882,7 @@ function admin_page_site(&$a) {
        /* get user names to make the install a personal install of X */
        $user_names = array();
        $user_names['---'] = t('Multi user instance');
-       $users = q("SELECT username, nickname FROM `user`");
+       $users = q("SELECT `username`, `nickname` FROM `user`");
        foreach ($users as $user) {
                $user_names[$user['nickname']] = $user['username'];
        }
@@ -902,6 +931,7 @@ function admin_page_site(&$a) {
                '$advanced' => t('Advanced'),
                '$portable_contacts' => t('Auto Discovered Contact Directory'),
                '$performance' => t('Performance'),
+               '$worker_title' => t('Worker'),
                '$relocate'=> t('Relocate - WARNING: advanced function. Could make this server unreachable.'),
                '$baseurl' => $a->get_baseurl(true),
                // name, label, value, help string, extra data...
@@ -947,6 +977,7 @@ function admin_page_site(&$a) {
                '$max_author_posts_community_page' => array('max_author_posts_community_page', t("Posts per user on community page"), get_config('system','max_author_posts_community_page'), t("The maximum number of posts per user on the community page. (Not valid for 'Global Community')")),
                '$ostatus_disabled'     => array('ostatus_disabled', t("Enable OStatus support"), !get_config('system','ostatus_disabled'), t("Provide built-in OStatus \x28StatusNet, GNU Social etc.\x29 compatibility. All communications in OStatus are public, so privacy warnings will be occasionally displayed.")),
                '$ostatus_poll_interval' => array('ostatus_poll_interval', t("OStatus conversation completion interval"), (string) intval(get_config('system','ostatus_poll_interval')), t("How often shall the poller check for new entries in OStatus conversations? This can be a very ressource task."), $ostatus_poll_choices),
+               '$ostatus_full_threads' => array('ostatus_full_threads', t("Only import OStatus threads from our contacts"), get_config('system','ostatus_full_threads'), t("Normally we import every content from our OStatus contacts. With this option we only store threads that are started by a contact that is known on our system.")),
                '$ostatus_not_able'     => t("OStatus support can only be enabled if threading is enabled."),
                '$diaspora_able'        => $diaspora_able,
                '$diaspora_not_able'    => t("Diaspora support can't be enabled because Friendica was installed into a sub directory."),
@@ -989,6 +1020,11 @@ function admin_page_site(&$a) {
                '$rino'                 => array('rino', t("RINO Encryption"), intval(get_config('system','rino_encrypt')), t("Encryption layer between nodes."), array("Disabled", "RINO1 (deprecated)", "RINO2")),
                '$embedly'              => array('embedly', t("Embedly API key"), get_config('system','embedly'), t("<a href='http://embed.ly'>Embedly</a> is used to fetch additional data for web pages. This is an optional parameter.")),
 
+               '$worker'               => array('worker', t("Enable 'worker' background processing"), get_config('system','worker'), t("The worker background processing limits the number of parallel background jobs to a maximum number and respects the system load.")),
+               '$worker_queues'        => array('worker_queues', t("Maximum number of parallel workers"), get_config('system','worker_queues'), t("On shared hosters set this to 2. On larger systems, values of 10 are great. Default value is 4.")),
+               '$worker_dont_fork'     => array('worker_dont_fork', t("Don't use 'proc_open' with the worker"), get_config('system','worker_dont_fork'), t("Enable this if your system doesn't allow the use of 'proc_open'. This can happen on shared hosters. If this is enabled you should increase the frequency of poller calls in your crontab.")),
+               '$worker_fastlane'      => array('worker_fastlane', t("Enable fastlane"), get_config('system','worker_fastlane'), t("When enabed, the fastlane mechanism starts an additional worker if processes with higher priority are blocked by processes of lower priority.")),
+
                '$form_security_token'  => get_form_security_token("admin_site")
 
        ));
@@ -1055,7 +1091,7 @@ function admin_page_dbsync(&$a) {
        }
 
        $failed = array();
-       $r = q("select k, v from config where `cat` = 'database' ");
+       $r = q("SELECT `k`, `v` FROM `config` WHERE `cat` = 'database' ");
        if(count($r)) {
                foreach($r as $rr) {
                        $upd = intval(substr($rr['k'],7));
@@ -1091,18 +1127,20 @@ function admin_page_dbsync(&$a) {
  * @param App $a
  */
 function admin_page_users_post(&$a){
-       $pending        =       (x($_POST, 'pending')                   ? $_POST['pending']             : array());
-       $users          =       (x($_POST, 'user')                      ? $_POST['user']                : array());
-       $nu_name        =       (x($_POST, 'new_user_name')             ? $_POST['new_user_name']       : '');
-       $nu_nickname    =       (x($_POST, 'new_user_nickname') ? $_POST['new_user_nickname']   : '');
-       $nu_email       =       (x($_POST, 'new_user_email')            ? $_POST['new_user_email']      : '');
+       $pending     =  (x($_POST, 'pending')                   ? $_POST['pending']             : array());
+       $users       =  (x($_POST, 'user')                      ? $_POST['user']                : array());
+       $nu_name     =  (x($_POST, 'new_user_name')             ? $_POST['new_user_name']       : '');
+       $nu_nickname =  (x($_POST, 'new_user_nickname')         ? $_POST['new_user_nickname']   : '');
+       $nu_email    =  (x($_POST, 'new_user_email')            ? $_POST['new_user_email']      : '');
+       $nu_language = get_config('system', 'language');
 
        check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
 
        if(!($nu_name==="") && !($nu_email==="") && !($nu_nickname==="")) {
                require_once('include/user.php');
 
-               $result = create_user(array('username'=>$nu_name, 'email'=>$nu_email, 'nickname'=>$nu_nickname, 'verified'=>1));
+               $result = create_user(array('username'=>$nu_name, 'email'=>$nu_email, 
+                       'nickname'=>$nu_nickname, 'verified'=>1, 'language'=>$nu_language));
                if(! $result['success']) {
                        notice($result['message']);
                        return;
@@ -1151,7 +1189,7 @@ function admin_page_users_post(&$a){
 
        if(x($_POST,'page_users_block')) {
                foreach($users as $uid){
-                       q("UPDATE `user` SET `blocked`=1-`blocked` WHERE `uid`=%s",
+                       q("UPDATE `user` SET `blocked` = 1-`blocked` WHERE `uid` = %s",
                                intval($uid)
                        );
                }
@@ -1196,7 +1234,7 @@ function admin_page_users_post(&$a){
 function admin_page_users(&$a){
        if($a->argc>2) {
                $uid = $a->argv[3];
-               $user = q("SELECT username, blocked FROM `user` WHERE `uid`=%d", intval($uid));
+               $user = q("SELECT `username`, `blocked` FROM `user` WHERE `uid` = %d", intval($uid));
                if(count($user)==0) {
                        notice('User not found'.EOL);
                        goaway('admin/users');
@@ -1213,7 +1251,7 @@ function admin_page_users(&$a){
                        }; break;
                        case "block":{
                                check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
-                               q("UPDATE `user` SET `blocked`=%d WHERE `uid`=%s",
+                               q("UPDATE `user` SET `blocked` = %d WHERE `uid` = %s",
                                        intval(1-$user[0]['blocked']),
                                        intval($uid)
                                );
@@ -1233,30 +1271,52 @@ function admin_page_users(&$a){
 
 
        /* get users */
-       $total = q("SELECT count(*) as total FROM `user` where 1");
+       $total = qu("SELECT COUNT(*) AS `total` FROM `user` WHERE 1");
        if(count($total)) {
                $a->set_pager_total($total[0]['total']);
                $a->set_pager_itemspage(100);
        }
 
-       $users = q("SELECT `user`.* , `contact`.`name` , `contact`.`url` , `contact`.`micro`, `lastitem`.`lastitem_date`, `user`.`account_expired`
-                               FROM
-                                       (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid`
-                                       FROM `item`
-                                       WHERE `item`.`type` = 'wall'
-                                       GROUP BY `item`.`uid`) AS `lastitem`
-                                                RIGHT OUTER JOIN `user` ON `user`.`uid` = `lastitem`.`uid`,
-                                          `contact`
-                               WHERE
-                                          `user`.`uid` = `contact`.`uid`
-                                               AND `user`.`verified` =1
-                                       AND `contact`.`self` =1
-                               ORDER BY `contact`.`name` LIMIT %d, %d
-                               ",
+       /* ordering */
+       $valid_orders = array(
+               'contact.name',
+               'user.email',
+               'user.register_date',
+               'user.login_date',
+               'lastitem_date',
+               'user.page-flags'
+       );
+
+       $order = "contact.name";
+       $order_direction = "+";
+       if (x($_GET,'o')){
+               $new_order = $_GET['o'];
+               if ($new_order[0]==="-") {
+                       $order_direction = "-";
+                       $new_order = substr($new_order,1);
+               }
+
+               if (in_array($new_order, $valid_orders)){
+                       $order = $new_order;
+               }
+               if (x($_GET,'d')){
+                       $new_direction = $_GET['d'];
+               }
+       }
+       $sql_order = "`".str_replace('.','`.`',$order)."`";
+       $sql_order_direction = ($order_direction==="+")?"ASC":"DESC";
+
+       $users = qu("SELECT `user`.*, `contact`.`name`, `contact`.`url`, `contact`.`micro`, `user`.`account_expired`, `contact`.`last-item` AS `lastitem_date`
+                               FROM `user`
+                               INNER JOIN `contact` ON `contact`.`uid` = `user`.`uid` AND `contact`.`self`
+                               WHERE `user`.`verified`
+                               ORDER BY $sql_order $sql_order_direction LIMIT %d, %d",
                                intval($a->pager['start']),
                                intval($a->pager['itemspage'])
                                );
 
+       //echo "<pre>$users"; killme();
+
        $adminlist = explode(",", str_replace(" ", "", $a->config['admin_email']));
        $_setup_users = function ($e) use ($adminlist){
                $accounts = array(
@@ -1303,6 +1363,11 @@ function admin_page_users(&$a){
                array_push($users, array_pop($tmp_users));
        }
 
+       $th_users = array_map(null,
+               array(t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'),  t('Account')),
+               $valid_orders
+       );
+       
        $t = get_markup_template("admin_users.tpl");
        $o = replace_macros($t, array(
                // strings //
@@ -1325,7 +1390,9 @@ function admin_page_users(&$a){
                '$h_users' => t('Users'),
                '$h_newuser' => t('New User'),
                '$th_deleted' => array(t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'), t('Deleted since')),
-               '$th_users' => array(t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'),  t('Account')),
+               '$th_users' => $th_users,
+               '$order_users' => $order,
+               '$order_direction_users' => $order_direction,
 
                '$confirm_delete_multi' => t('Selected users will be deleted!\n\nEverything these users had posted on this site will be permanently deleted!\n\nAre you sure?'),
                '$confirm_delete' => t('The user {0} will be deleted!\n\nEverything this user has posted on this site will be permanently deleted!\n\nAre you sure?'),
@@ -1787,12 +1854,18 @@ function admin_page_logs_post(&$a) {
 function admin_page_logs(&$a){
 
        $log_choices = array(
-               LOGGER_NORMAL => 'Normal',
-               LOGGER_TRACE => 'Trace',
-               LOGGER_DEBUG => 'Debug',
-               LOGGER_DATA => 'Data',
-               LOGGER_ALL => 'All'
+               LOGGER_NORMAL   => 'Normal',
+               LOGGER_TRACE    => 'Trace',
+               LOGGER_DEBUG    => 'Debug',
+               LOGGER_DATA     => 'Data',
+               LOGGER_ALL      => 'All'
        );
+       
+       if (ini_get('log_errors')) {
+               $phplogenabled = t('PHP log currently enabled.');
+       } else {
+               $phplogenabled = t('PHP log currently disabled.');
+       }
 
        $t = get_markup_template("admin_logs.tpl");
 
@@ -1813,6 +1886,7 @@ function admin_page_logs(&$a){
                '$phpheader' => t("PHP logging"),
                '$phphint' => t("To enable logging of PHP errors and warnings you can add the following to the .htconfig.php file of your installation. The filename set in the 'error_log' line is relative to the friendica top-level directory and must be writeable by the web server. The option '1' for 'log_errors' and 'display_errors' is to enable these options, set to '0' to disable them."),
                '$phplogcode' => "error_reporting(E_ERROR | E_WARNING | E_PARSE);\nini_set('error_log','php.out');\nini_set('log_errors','1');\nini_set('display_errors', '1');",
+               '$phplogenabled' => $phplogenabled,
        ));
 }