]> git.mxchange.org Git - friendica.git/blob - mod/admin.php
admin panel: inspect queue
[friendica.git] / mod / admin.php
1 <?php
2
3  /**
4   * Friendica admin
5   */
6 require_once("include/remoteupdate.php");
7 require_once("include/enotify.php");
8 require_once("include/text.php");
9
10
11 /**
12  * @param App $a
13  */
14 function admin_post(&$a){
15
16
17         if(!is_site_admin()) {
18                 return;
19         }
20
21         // do not allow a page manager to access the admin panel at all.
22
23         if(x($_SESSION,'submanage') && intval($_SESSION['submanage']))
24                 return;
25
26
27
28         // urls
29         if ($a->argc > 1){
30                 switch ($a->argv[1]){
31                         case 'site':
32                                 admin_page_site_post($a);
33                                 break;
34                         case 'users':
35                                 admin_page_users_post($a);
36                                 break;
37                         case 'plugins':
38                                 if ($a->argc > 2 &&
39                                         is_file("addon/".$a->argv[2]."/".$a->argv[2].".php")){
40                                                 @include_once("addon/".$a->argv[2]."/".$a->argv[2].".php");
41                                                 if(function_exists($a->argv[2].'_plugin_admin_post')) {
42                                                         $func = $a->argv[2].'_plugin_admin_post';
43                                                         $func($a);
44                                                 }
45                                 }
46                                 goaway($a->get_baseurl(true) . '/admin/plugins/' . $a->argv[2] );
47                                 return; // NOTREACHED
48                                 break;
49                         case 'themes':
50                                 $theme = $a->argv[2];
51                                 if (is_file("view/theme/$theme/config.php")){
52                                         require_once("view/theme/$theme/config.php");
53                                         if (function_exists("theme_admin_post")){
54                                                 theme_admin_post($a);
55                                         }
56                                 }
57                                 info(t('Theme settings updated.'));
58                                 if(is_ajax()) return;
59
60                                 goaway($a->get_baseurl(true) . '/admin/themes/' . $theme );
61                                 return;
62                                 break;
63                         case 'logs':
64                                 admin_page_logs_post($a);
65                                 break;
66                         case 'dbsync':
67                                 admin_page_dbsync_post($a);
68                                 break;
69                         case 'update':
70                                 admin_page_remoteupdate_post($a);
71                                 break;
72                 }
73         }
74
75         goaway($a->get_baseurl(true) . '/admin' );
76         return; // NOTREACHED
77 }
78
79 /**
80  * @param App $a
81  * @return string
82  */
83 function admin_content(&$a) {
84
85         if(!is_site_admin()) {
86                 return login(false);
87         }
88
89         if(x($_SESSION,'submanage') && intval($_SESSION['submanage']))
90                 return "";
91
92         // APC deactivated, since there are problems with PHP 5.5
93         //if (function_exists("apc_delete")) {
94         //      $toDelete = new APCIterator('user', APC_ITER_VALUE);
95         //      apc_delete($toDelete);
96         //}
97
98         /**
99          * Side bar links
100          */
101
102         // array( url, name, extra css classes )
103         $aside = Array(
104                 'site'   =>     Array($a->get_baseurl(true)."/admin/site/", t("Site") , "site"),
105                 'users'  =>     Array($a->get_baseurl(true)."/admin/users/", t("Users") , "users"),
106                 'plugins'=>     Array($a->get_baseurl(true)."/admin/plugins/", t("Plugins") , "plugins"),
107                 'themes' =>     Array($a->get_baseurl(true)."/admin/themes/", t("Themes") , "themes"),
108                 'dbsync' =>     Array($a->get_baseurl(true)."/admin/dbsync/", t('DB updates'), "dbsync"),
109                 'queue'  =>     Array($a->get_baseurl(true)."/admin/queue/", t('Inspect Queue'), "queue"),
110                 //'update' =>   Array($a->get_baseurl(true)."/admin/update/", t("Software Update") , "update")
111         );
112
113         /* get plugins admin page */
114
115         $r = q("SELECT name FROM `addon` WHERE `plugin_admin`=1");
116         $aside['plugins_admin']=Array();
117         foreach ($r as $h){
118                 $plugin =$h['name'];
119                 $aside['plugins_admin'][] = Array($a->get_baseurl(true)."/admin/plugins/".$plugin, $plugin, "plugin");
120                 // temp plugins with admin
121                 $a->plugins_admin[] = $plugin;
122         }
123
124         $aside['logs'] = Array($a->get_baseurl(true)."/admin/logs/", t("Logs"), "logs");
125         $aside['diagnostics_probe'] = Array($a->get_baseurl(true).'/probe/', t('probe address'), 'probe');
126         $aside['diagnostics_webfinger'] = Array($a->get_baseurl(true).'/webfinger/', t('check webfinger'), 'webfinger');
127
128         $t = get_markup_template("admin_aside.tpl");
129         $a->page['aside'] .= replace_macros( $t, array(
130                         '$admin' => $aside,
131                         '$admtxt' => t('Admin'),
132                         '$plugadmtxt' => t('Plugin Features'),
133                         '$logtxt' => t('Logs'),
134                         '$diagnosticstxt' => t('diagnostics'),
135                         '$h_pending' => t('User registrations waiting for confirmation'),
136                         '$admurl'=> $a->get_baseurl(true)."/admin/"
137         ));
138
139
140
141         /**
142          * Page content
143          */
144         $o = '';
145         // urls
146         if ($a->argc > 1){
147                 switch ($a->argv[1]){
148                         case 'site':
149                                 $o = admin_page_site($a);
150                                 break;
151                         case 'users':
152                                 $o = admin_page_users($a);
153                                 break;
154                         case 'plugins':
155                                 $o = admin_page_plugins($a);
156                                 break;
157                         case 'themes':
158                                 $o = admin_page_themes($a);
159                                 break;
160                         case 'logs':
161                                 $o = admin_page_logs($a);
162                                 break;
163                         case 'dbsync':
164                                 $o = admin_page_dbsync($a);
165                                 break;
166                         case 'update':
167                                 $o = admin_page_remoteupdate($a);
168                                 break;
169                         case 'queue':
170                                 $o = admin_page_queue($a);
171                                 break;
172                         default:
173                                 notice( t("Item not found.") );
174                 }
175         } else {
176                 $o = admin_page_summary($a);
177         }
178
179         if(is_ajax()) {
180                 echo $o;
181                 killme();
182                 return '';
183         } else {
184                 return $o;
185         }
186 }
187
188 /**
189  * Admin Inspect Queue Page
190  * @param App $a
191  * return string
192  */
193 function admin_page_queue(&$a) {
194         // get content from the queue table
195         $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;");
196
197         $t = get_markup_template("admin_queue.tpl");
198         return replace_macros($t, array(
199                 '$title' => t('Administration'),
200                 '$page' => t('Inspect Queue'),
201                 '$count' => sizeof($r),
202                 'id_header' => t('ID'),
203                 '$to_header' => t('Recipient Name'),
204                 '$url_header' => t('Recipient Profile'),
205                 '$network_header' => t('Network'),
206                 '$created_header' => t('Created'),
207                 '$last_header' => t('Last Tried'),
208                 '$info' => t('This page lists the content of the queue for outgoing postings. These are postings the initial delivery failed for. They will be resend later and eventually deleted if the delivery fails permanently.'),
209                 '$entries' => $r,
210         ));
211 }
212 /**
213  * Admin Summary Page
214  * @param App $a
215  * @return string
216  */
217 function admin_page_summary(&$a) {
218         $r = q("SELECT `page-flags`, COUNT(uid) as `count` FROM `user` GROUP BY `page-flags`");
219         $accounts = Array(
220                 Array( t('Normal Account'), 0),
221                 Array( t('Soapbox Account'), 0),
222                 Array( t('Community/Celebrity Account'), 0),
223                 Array( t('Automatic Friend Account'), 0),
224                 Array( t('Blog Account'), 0),
225                 Array( t('Private Forum'), 0)
226         );
227
228         $users=0;
229         foreach ($r as $u){ $accounts[$u['page-flags']][1] = $u['count']; $users+= $u['count']; }
230
231         logger('accounts: ' . print_r($accounts,true),LOGGER_DATA);
232
233         $r = q("SELECT COUNT(id) as `count` FROM `register`");
234         $pending = $r[0]['count'];
235
236         $r = q("select count(*) as total from deliverq where 1");
237         $deliverq = (($r) ? $r[0]['total'] : 0);
238
239         $r = q("select count(*) as total from queue where 1");
240         $queue = (($r) ? $r[0]['total'] : 0);
241
242         // We can do better, but this is a quick queue status
243
244         $queues = array( 'label' => t('Message queues'), 'deliverq' => $deliverq, 'queue' => $queue );
245
246
247         $t = get_markup_template("admin_summary.tpl");
248         return replace_macros($t, array(
249                 '$title' => t('Administration'),
250                 '$page' => t('Summary'),
251                 '$queues' => $queues,
252                 '$users' => Array( t('Registered users'), $users),
253                 '$accounts' => $accounts,
254                 '$pending' => Array( t('Pending registrations'), $pending),
255                 '$version' => Array( t('Version'), FRIENDICA_VERSION),
256                 '$platform' => FRIENDICA_PLATFORM,
257                 '$codename' => FRIENDICA_CODENAME,
258                 '$build' =>  get_config('system','build'),
259                 '$plugins' => Array( t('Active plugins'), $a->plugins )
260         ));
261 }
262
263
264 /**
265  * Admin Site Page
266  *  @param App $a
267  */
268 function admin_page_site_post(&$a){
269         if (!x($_POST,"page_site")){
270                 return;
271         }
272
273         check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
274
275         // relocate
276         if (x($_POST,'relocate') && x($_POST,'relocate_url') && $_POST['relocate_url']!=""){
277                 $new_url = $_POST['relocate_url'];
278                 $new_url = rtrim($new_url,"/");
279
280                 $parsed = @parse_url($new_url);
281                 if (!$parsed || (!x($parsed,'host') || !x($parsed,'scheme'))) {
282                         notice(t("Can not parse base url. Must have at least <scheme>://<domain>"));
283                         goaway($a->get_baseurl(true) . '/admin/site' );
284                 }
285
286                 /* steps:
287                  * replace all "baseurl" to "new_url" in config, profile, term, items and contacts
288                  * send relocate for every local user
289                  * */
290
291                 $old_url = $a->get_baseurl(true);
292
293                 function update_table($table_name, $fields, $old_url, $new_url) {
294                         global $db, $a;
295
296                         $dbold = dbesc($old_url);
297                         $dbnew = dbesc($new_url);
298
299                         $upd = array();
300                         foreach ($fields as $f) {
301                                 $upd[] = "`$f` = REPLACE(`$f`, '$dbold', '$dbnew')";
302                         }
303
304                         $upds = implode(", ", $upd);
305
306
307
308                         $q = sprintf("UPDATE %s SET %s;", $table_name, $upds);
309                         $r = q($q);
310                         if (!$r) {
311                                 notice( "Failed updating '$table_name': " . $db->error );
312                                 goaway($a->get_baseurl(true) . '/admin/site' );
313                         }
314                 }
315
316                 // update tables
317                 update_table("profile", array('photo', 'thumb'), $old_url, $new_url);
318                 update_table("term", array('url'), $old_url, $new_url);
319                 update_table("contact", array('photo','thumb','micro','url','nurl','request','notify','poll','confirm','poco'), $old_url, $new_url);
320                 update_table("unique_contacts", array('url'), $old_url, $new_url);
321                 update_table("item", array('owner-link','owner-avatar','author-name','author-link','author-avatar','body','plink','tag'), $old_url, $new_url);
322
323                 // update config
324                 $a->set_baseurl($new_url);
325                 set_config('system','url',$new_url);
326
327                 // send relocate
328                 $users = q("SELECT uid FROM user WHERE account_removed = 0 AND account_expired = 0");
329
330                 foreach ($users as $user) {
331                         proc_run('php', 'include/notifier.php', 'relocate', $user['uid']);
332                 }
333
334                 info("Relocation started. Could take a while to complete.");
335
336                 goaway($a->get_baseurl(true) . '/admin/site' );
337         }
338         // end relocate
339
340         $sitename               =       ((x($_POST,'sitename'))                 ? notags(trim($_POST['sitename']))              : '');
341         $hostname               =       ((x($_POST,'hostname'))                 ? notags(trim($_POST['hostname']))              : '');
342         $sender_email           =       ((x($_POST,'sender_email'))             ? notags(trim($_POST['sender_email']))          : '');
343         $banner                 =       ((x($_POST,'banner'))                   ? trim($_POST['banner'])                        : false);
344         $shortcut_icon          =       ((x($_POST,'shortcut_icon'))            ? notags(trim($_POST['shortcut_icon']))         : '');
345         $touch_icon             =       ((x($_POST,'touch_icon'))               ? notags(trim($_POST['touch_icon']))            : '');
346         $info                   =       ((x($_POST,'info'))                     ? trim($_POST['info'])                  : false);
347         $language               =       ((x($_POST,'language'))                 ? notags(trim($_POST['language']))              : '');
348         $theme                  =       ((x($_POST,'theme'))                    ? notags(trim($_POST['theme']))                 : '');
349         $theme_mobile           =       ((x($_POST,'theme_mobile'))             ? notags(trim($_POST['theme_mobile']))          : '');
350         $maximagesize           =       ((x($_POST,'maximagesize'))             ? intval(trim($_POST['maximagesize']))          :  0);
351         $maximagelength         =       ((x($_POST,'maximagelength'))           ? intval(trim($_POST['maximagelength']))        :  MAX_IMAGE_LENGTH);
352         $jpegimagequality       =       ((x($_POST,'jpegimagequality'))         ? intval(trim($_POST['jpegimagequality']))      :  JPEG_QUALITY);
353
354
355         $register_policy        =       ((x($_POST,'register_policy'))          ? intval(trim($_POST['register_policy']))       :  0);
356         $daily_registrations    =       ((x($_POST,'max_daily_registrations'))  ? intval(trim($_POST['max_daily_registrations']))       :0);
357         $abandon_days           =       ((x($_POST,'abandon_days'))             ? intval(trim($_POST['abandon_days']))          :  0);
358
359         $register_text          =       ((x($_POST,'register_text'))            ? notags(trim($_POST['register_text']))         : '');
360
361         $allowed_sites          =       ((x($_POST,'allowed_sites'))            ? notags(trim($_POST['allowed_sites']))         : '');
362         $allowed_email          =       ((x($_POST,'allowed_email'))            ? notags(trim($_POST['allowed_email']))         : '');
363         $block_public           =       ((x($_POST,'block_public'))             ? True                                          : False);
364         $force_publish          =       ((x($_POST,'publish_all'))              ? True                                          : False);
365         $global_directory       =       ((x($_POST,'directory_submit_url'))     ? notags(trim($_POST['directory_submit_url']))  : '');
366         $thread_allow           =       ((x($_POST,'thread_allow'))             ? True                                          : False);
367         $newuser_private                =       ((x($_POST,'newuser_private'))          ? True                                          : False);
368         $enotify_no_content             =       ((x($_POST,'enotify_no_content'))       ? True                                          : False);
369         $private_addons                 =       ((x($_POST,'private_addons'))           ? True                                          : False);
370         $disable_embedded               =       ((x($_POST,'disable_embedded'))         ? True                                          : False);
371         $allow_users_remote_self        =       ((x($_POST,'allow_users_remote_self'))          ? True                                          : False);
372
373         $no_multi_reg           =       ((x($_POST,'no_multi_reg'))             ? True                                          : False);
374         $no_openid              =       !((x($_POST,'no_openid'))               ? True                                          : False);
375         $no_regfullname         =       !((x($_POST,'no_regfullname'))          ? True                                          : False);
376         $no_utf                 =       !((x($_POST,'no_utf'))                  ? True                                          : False);
377         $community_page_style   =       ((x($_POST,'community_page_style'))     ? intval(trim($_POST['community_page_style']))  : 0);
378         $max_author_posts_community_page        =       ((x($_POST,'max_author_posts_community_page'))  ? intval(trim($_POST['max_author_posts_community_page']))       : 0);
379
380         $verifyssl              =       ((x($_POST,'verifyssl'))                ? True                                          : False);
381         $proxyuser              =       ((x($_POST,'proxyuser'))                ? notags(trim($_POST['proxyuser']))             : '');
382         $proxy                  =       ((x($_POST,'proxy'))                    ? notags(trim($_POST['proxy']))                 : '');
383         $timeout                =       ((x($_POST,'timeout'))                  ? intval(trim($_POST['timeout']))               : 60);
384         $delivery_interval      =       ((x($_POST,'delivery_interval'))        ? intval(trim($_POST['delivery_interval']))     : 0);
385         $poll_interval          =       ((x($_POST,'poll_interval'))            ? intval(trim($_POST['poll_interval']))         : 0);
386         $maxloadavg             =       ((x($_POST,'maxloadavg'))               ? intval(trim($_POST['maxloadavg']))            : 50);
387         $maxloadavg_frontend    =       ((x($_POST,'maxloadavg_frontend'))      ? intval(trim($_POST['maxloadavg_frontend']))   : 50);
388         $poco_completion        =       ((x($_POST,'poco_completion'))          ? intval(trim($_POST['poco_completion']))       : false);
389         $poco_discovery         =       ((x($_POST,'poco_discovery'))           ? intval(trim($_POST['poco_discovery']))        : 0);
390         $poco_discovery_since   =       ((x($_POST,'poco_discovery_since'))     ? intval(trim($_POST['poco_discovery_since']))  : 30);
391         $poco_local_search      =       ((x($_POST,'poco_local_search'))        ? intval(trim($_POST['poco_local_search']))     : false);
392         $dfrn_only              =       ((x($_POST,'dfrn_only'))                ? True                                          : False);
393         $ostatus_disabled       =       !((x($_POST,'ostatus_disabled'))        ? True                                          : False);
394         $ostatus_poll_interval  =       ((x($_POST,'ostatus_poll_interval'))    ? intval(trim($_POST['ostatus_poll_interval'])) :  0);
395         $diaspora_enabled       =       ((x($_POST,'diaspora_enabled'))         ? True                                          : False);
396         $ssl_policy             =       ((x($_POST,'ssl_policy'))               ? intval($_POST['ssl_policy'])                  : 0);
397         $force_ssl              =       ((x($_POST,'force_ssl'))                ? True                                          : False);
398         $old_share              =       ((x($_POST,'old_share'))                ? True                                          : False);
399         $hide_help              =       ((x($_POST,'hide_help'))                ? True                                          : False);
400         $suppress_language      =       ((x($_POST,'suppress_language'))        ? True                                          : False);
401         $suppress_tags          =       ((x($_POST,'suppress_tags'))            ? True                                          : False);
402         $use_fulltext_engine    =       ((x($_POST,'use_fulltext_engine'))      ? True                                          : False);
403         $itemcache              =       ((x($_POST,'itemcache'))                ? notags(trim($_POST['itemcache']))             : '');
404         $itemcache_duration     =       ((x($_POST,'itemcache_duration'))       ? intval($_POST['itemcache_duration'])          : 0);
405         $max_comments           =       ((x($_POST,'max_comments'))             ? intval($_POST['max_comments'])                : 0);
406         $lockpath               =       ((x($_POST,'lockpath'))                 ? notags(trim($_POST['lockpath']))              : '');
407         $temppath               =       ((x($_POST,'temppath'))                 ? notags(trim($_POST['temppath']))              : '');
408         $basepath               =       ((x($_POST,'basepath'))                 ? notags(trim($_POST['basepath']))              : '');
409         $singleuser             =       ((x($_POST,'singleuser'))               ? notags(trim($_POST['singleuser']))            : '');
410         $proxy_disabled         =       ((x($_POST,'proxy_disabled'))           ? True                                          : False);
411         $old_pager              =       ((x($_POST,'old_pager'))                ? True                                          : False);
412         $only_tag_search        =       ((x($_POST,'only_tag_search'))          ? True                                          : False);
413         $rino                   =       ((x($_POST,'rino'))                             ? intval($_POST['rino'])                                : 0);
414
415
416         if($ssl_policy != intval(get_config('system','ssl_policy'))) {
417                 if($ssl_policy == SSL_POLICY_FULL) {
418                         q("update `contact` set
419                                 `url`     = replace(`url`    , 'http:' , 'https:'),
420                                 `photo`   = replace(`photo`  , 'http:' , 'https:'),
421                                 `thumb`   = replace(`thumb`  , 'http:' , 'https:'),
422                                 `micro`   = replace(`micro`  , 'http:' , 'https:'),
423                                 `request` = replace(`request`, 'http:' , 'https:'),
424                                 `notify`  = replace(`notify` , 'http:' , 'https:'),
425                                 `poll`    = replace(`poll`   , 'http:' , 'https:'),
426                                 `confirm` = replace(`confirm`, 'http:' , 'https:'),
427                                 `poco`    = replace(`poco`   , 'http:' , 'https:')
428                                 where `self` = 1"
429                         );
430                         q("update `profile` set
431                                 `photo`   = replace(`photo`  , 'http:' , 'https:'),
432                                 `thumb`   = replace(`thumb`  , 'http:' , 'https:')
433                                 where 1 "
434                         );
435                 }
436                 elseif($ssl_policy == SSL_POLICY_SELFSIGN) {
437                         q("update `contact` set
438                                 `url`     = replace(`url`    , 'https:' , 'http:'),
439                                 `photo`   = replace(`photo`  , 'https:' , 'http:'),
440                                 `thumb`   = replace(`thumb`  , 'https:' , 'http:'),
441                                 `micro`   = replace(`micro`  , 'https:' , 'http:'),
442                                 `request` = replace(`request`, 'https:' , 'http:'),
443                                 `notify`  = replace(`notify` , 'https:' , 'http:'),
444                                 `poll`    = replace(`poll`   , 'https:' , 'http:'),
445                                 `confirm` = replace(`confirm`, 'https:' , 'http:'),
446                                 `poco`    = replace(`poco`   , 'https:' , 'http:')
447                                 where `self` = 1"
448                         );
449                         q("update `profile` set
450                                 `photo`   = replace(`photo`  , 'https:' , 'http:'),
451                                 `thumb`   = replace(`thumb`  , 'https:' , 'http:')
452                                 where 1 "
453                         );
454                 }
455         }
456         set_config('system','ssl_policy',$ssl_policy);
457         set_config('system','delivery_interval',$delivery_interval);
458         set_config('system','poll_interval',$poll_interval);
459         set_config('system','maxloadavg',$maxloadavg);
460         set_config('system','maxloadavg_frontend',$maxloadavg_frontend);
461         set_config('system','poco_completion',$poco_completion);
462         set_config('system','poco_discovery',$poco_discovery);
463         set_config('system','poco_discovery_since',$poco_discovery_since);
464         set_config('system','poco_local_search',$poco_local_search);
465         set_config('config','sitename',$sitename);
466         set_config('config','hostname',$hostname);
467         set_config('config','sender_email', $sender_email);
468         set_config('system','suppress_language',$suppress_language);
469         set_config('system','suppress_tags',$suppress_tags);
470         set_config('system','shortcut_icon',$shortcut_icon);
471         set_config('system','touch_icon',$touch_icon);
472
473         if ($banner==""){
474                 // don't know why, but del_config doesn't work...
475                 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
476                         dbesc("system"),
477                         dbesc("banner")
478                 );
479         } else {
480                 set_config('system','banner', $banner);
481         }
482         if ($info=="") {
483                 del_config('config','info');
484         } else {
485                 set_config('config','info',$info);
486         }
487         set_config('system','language', $language);
488         set_config('system','theme', $theme);
489         if ( $theme_mobile === '---' ) {
490                 del_config('system','mobile-theme');
491         } else {
492                 set_config('system','mobile-theme', $theme_mobile);
493                 }
494                 if ( $singleuser === '---' ) {
495                         del_config('system','singleuser');
496                 } else {
497                         set_config('system','singleuser', $singleuser);
498                 }
499         set_config('system','maximagesize', $maximagesize);
500         set_config('system','max_image_length', $maximagelength);
501         set_config('system','jpeg_quality', $jpegimagequality);
502
503         set_config('config','register_policy', $register_policy);
504         set_config('system','max_daily_registrations', $daily_registrations);
505         set_config('system','account_abandon_days', $abandon_days);
506         set_config('config','register_text', $register_text);
507         set_config('system','allowed_sites', $allowed_sites);
508         set_config('system','allowed_email', $allowed_email);
509         set_config('system','block_public', $block_public);
510         set_config('system','publish_all', $force_publish);
511         if ($global_directory==""){
512                 // don't know why, but del_config doesn't work...
513                 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
514                         dbesc("system"),
515                         dbesc("directory_submit_url")
516                 );
517         } else {
518                 set_config('system','directory_submit_url', $global_directory);
519         }
520         set_config('system','thread_allow', $thread_allow);
521         set_config('system','newuser_private', $newuser_private);
522         set_config('system','enotify_no_content', $enotify_no_content);
523         set_config('system','disable_embedded', $disable_embedded);
524         set_config('system','allow_users_remote_self', $allow_users_remote_self);
525
526         set_config('system','block_extended_register', $no_multi_reg);
527         set_config('system','no_openid', $no_openid);
528         set_config('system','no_regfullname', $no_regfullname);
529         set_config('system','community_page_style', $community_page_style);
530         set_config('system','max_author_posts_community_page', $max_author_posts_community_page);
531         set_config('system','no_utf', $no_utf);
532         set_config('system','verifyssl', $verifyssl);
533         set_config('system','proxyuser', $proxyuser);
534         set_config('system','proxy', $proxy);
535         set_config('system','curl_timeout', $timeout);
536         set_config('system','dfrn_only', $dfrn_only);
537         set_config('system','ostatus_disabled', $ostatus_disabled);
538         set_config('system','ostatus_poll_interval', $ostatus_poll_interval);
539         set_config('system','diaspora_enabled', $diaspora_enabled);
540         set_config('config','private_addons', $private_addons);
541
542         set_config('system','force_ssl', $force_ssl);
543         set_config('system','old_share', $old_share);
544         set_config('system','hide_help', $hide_help);
545         set_config('system','use_fulltext_engine', $use_fulltext_engine);
546         set_config('system','itemcache', $itemcache);
547         set_config('system','itemcache_duration', $itemcache_duration);
548         set_config('system','max_comments', $max_comments);
549         set_config('system','lockpath', $lockpath);
550         set_config('system','temppath', $temppath);
551         set_config('system','basepath', $basepath);
552         set_config('system','proxy_disabled', $proxy_disabled);
553         set_config('system','old_pager', $old_pager);
554         set_config('system','only_tag_search', $only_tag_search);
555
556         set_config('system','rino_encrypt', $rino);
557         
558         
559         info( t('Site settings updated.') . EOL);
560         goaway($a->get_baseurl(true) . '/admin/site' );
561         return; // NOTREACHED
562
563 }
564
565 /**
566  * @param  App $a
567  * @return string
568  */
569 function admin_page_site(&$a) {
570
571         /* Installed langs */
572         $lang_choices = array();
573         $langs = glob('view/*/strings.php');
574
575         if(is_array($langs) && count($langs)) {
576                 if(! in_array('view/en/strings.php',$langs))
577                         $langs[] = 'view/en/';
578                 asort($langs);
579                 foreach($langs as $l) {
580                         $t = explode("/",$l);
581                         $lang_choices[$t[1]] = $t[1];
582                 }
583         }
584
585         /* Installed themes */
586         $theme_choices = array();
587         $theme_choices_mobile = array();
588         $theme_choices_mobile["---"] = t("No special theme for mobile devices");
589         $files = glob('view/theme/*');
590         if($files) {
591                 foreach($files as $file) {
592                         $f = basename($file);
593                         $theme_name = ((file_exists($file . '/experimental')) ?  sprintf("%s - \x28Experimental\x29", $f) : $f);
594                         if (file_exists($file . '/mobile')) {
595                                 $theme_choices_mobile[$f] = $theme_name;
596                         }
597                 else {
598                                 $theme_choices[$f] = $theme_name;
599                         }
600                 }
601                 }
602
603                 /* Community page style */
604                 $community_page_style_choices = array(
605                         CP_NO_COMMUNITY_PAGE => t("No community page"),
606                         CP_USERS_ON_SERVER => t("Public postings from users of this site"),
607                         CP_GLOBAL_COMMUNITY => t("Global community page")
608                         );
609
610                 /* OStatus conversation poll choices */
611                 $ostatus_poll_choices = array(
612                         "-2" => t("Never"),
613                         "-1" => t("At post arrival"),
614                         "0" => t("Frequently"),
615                         "60" => t("Hourly"),
616                         "720" => t("Twice daily"),
617                         "1440" => t("Daily")
618                         );
619
620                 $poco_discovery_choices = array(
621                         "0" => t("Disabled"),
622                         "1" => t("Users"),
623                         "2" => t("Users, Global Contacts"),
624                         "3" => t("Users, Global Contacts/fallback"),
625                         );
626
627                 $poco_discovery_since_choices = array(
628                         "30" => t("One month"),
629                         "91" => t("Three months"),
630                         "182" => t("Half a year"),
631                         "365" => t("One year"),
632                         );
633
634                 /* get user names to make the install a personal install of X */
635                 $user_names = array();
636                 $user_names['---'] = t('Multi user instance');
637                 $users = q("SELECT username, nickname FROM `user`");
638                 foreach ($users as $user) {
639                         $user_names[$user['nickname']] = $user['username'];
640                 }
641
642         /* Banner */
643         $banner = get_config('system','banner');
644         if($banner == false)
645                 $banner = '<a href="http://friendica.com"><img id="logo-img" src="images/friendica-32.png" alt="logo" /></a><span id="logo-text"><a href="http://friendica.com">Friendica</a></span>';
646         $banner = htmlspecialchars($banner);
647         $info = get_config('config','info');
648         $info = htmlspecialchars($info);
649
650         // Automatically create temporary paths
651         get_temppath();
652         get_lockpath();
653         get_itemcachepath();
654
655         //echo "<pre>"; var_dump($lang_choices); die("</pre>");
656
657         /* Register policy */
658         $register_choices = Array(
659                 REGISTER_CLOSED => t("Closed"),
660                 REGISTER_APPROVE => t("Requires approval"),
661                 REGISTER_OPEN => t("Open")
662         );
663
664         $ssl_choices = array(
665                 SSL_POLICY_NONE => t("No SSL policy, links will track page SSL state"),
666                 SSL_POLICY_FULL => t("Force all links to use SSL"),
667                 SSL_POLICY_SELFSIGN => t("Self-signed certificate, use SSL for local links only (discouraged)")
668         );
669
670         if ($a->config['hostname'] == "")
671                 $a->config['hostname'] = $a->get_hostname();
672
673         $t = get_markup_template("admin_site.tpl");
674         return replace_macros($t, array(
675                 '$title' => t('Administration'),
676                 '$page' => t('Site'),
677                 '$submit' => t('Save Settings'),
678                 '$registration' => t('Registration'),
679                 '$upload' => t('File upload'),
680                 '$corporate' => t('Policies'),
681                 '$advanced' => t('Advanced'),
682                 '$portable_contacts' => t('Auto Discovered Contact Directory'),
683                 '$performance' => t('Performance'),
684                 '$relocate'=> t('Relocate - WARNING: advanced function. Could make this server unreachable.'),
685                 '$baseurl' => $a->get_baseurl(true),
686                 // name, label, value, help string, extra data...
687                 '$sitename'             => array('sitename', t("Site name"), $a->config['sitename'],'UTF-8'),
688                 '$hostname'             => array('hostname', t("Host name"), $a->config['hostname'], ""),
689                 '$sender_email'         => array('sender_email', t("Sender Email"), $a->config['sender_email'], "The email address your server shall use to send notification emails from.", "", "", "email"),
690                 '$banner'               => array('banner', t("Banner/Logo"), $banner, ""),
691                 '$shortcut_icon'        => array('shortcut_icon', t("Shortcut icon"), get_config('system','shortcut_icon'),  "Link to an icon that will be used for browsers."),
692                 '$touch_icon'           => array('touch_icon', t("Touch icon"), get_config('system','touch_icon'),  "Link to an icon that will be used for tablets and mobiles."),
693                 '$info' => array('info',t('Additional Info'), $info, t('For public servers: you can add additional information here that will be listed at dir.friendica.com/siteinfo.')),
694                 '$language'             => array('language', t("System language"), get_config('system','language'), "", $lang_choices),
695                 '$theme'                => array('theme', t("System theme"), get_config('system','theme'), t("Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"), $theme_choices),
696                 '$theme_mobile'         => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile-theme'), t("Theme for mobile devices"), $theme_choices_mobile),
697                 '$ssl_policy'           => array('ssl_policy', t("SSL link policy"), (string) intval(get_config('system','ssl_policy')), t("Determines whether generated links should be forced to use SSL"), $ssl_choices),
698                 '$force_ssl'            => array('force_ssl', t("Force SSL"), get_config('system','force_ssl'), t("Force all Non-SSL requests to SSL - Attention: on some systems it could lead to endless loops.")),
699                 '$old_share'            => array('old_share', t("Old style 'Share'"), get_config('system','old_share'), t("Deactivates the bbcode element 'share' for repeating items.")),
700                 '$hide_help'            => array('hide_help', t("Hide help entry from navigation menu"), get_config('system','hide_help'), t("Hides the menu entry for the Help pages from the navigation menu. You can still access it calling /help directly.")),
701                 '$singleuser'           => array('singleuser', t("Single user instance"), get_config('system','singleuser'), t("Make this instance multi-user or single-user for the named user"), $user_names),
702                 '$maximagesize'         => array('maximagesize', t("Maximum image size"), get_config('system','maximagesize'), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")),
703                 '$maximagelength'               => array('maximagelength', t("Maximum image length"), get_config('system','max_image_length'), t("Maximum length in pixels of the longest side of uploaded images. Default is -1, which means no limits.")),
704                 '$jpegimagequality'             => array('jpegimagequality', t("JPEG image quality"), get_config('system','jpeg_quality'), t("Uploaded JPEGS will be saved at this quality setting [0-100]. Default is 100, which is full quality.")),
705
706                 '$register_policy'      => array('register_policy', t("Register policy"), $a->config['register_policy'], "", $register_choices),
707                 '$daily_registrations'  => array('max_daily_registrations', t("Maximum Daily Registrations"), get_config('system', 'max_daily_registrations'), t("If registration is permitted above, this sets the maximum number of new user registrations to accept per day.  If register is set to closed, this setting has no effect.")),
708                 '$register_text'        => array('register_text', t("Register text"), $a->config['register_text'], t("Will be displayed prominently on the registration page.")),
709                 '$abandon_days'         => array('abandon_days', t('Accounts abandoned after x days'), get_config('system','account_abandon_days'), t('Will not waste system resources polling external sites for abandonded accounts. Enter 0 for no time limit.')),
710                 '$allowed_sites'        => array('allowed_sites', t("Allowed friend domains"), get_config('system','allowed_sites'), t("Comma separated list of domains which are allowed to establish friendships with this site. Wildcards are accepted. Empty to allow any domains")),
711                 '$allowed_email'        => array('allowed_email', t("Allowed email domains"), get_config('system','allowed_email'), t("Comma separated list of domains which are allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains")),
712                 '$block_public'         => array('block_public', t("Block public"), get_config('system','block_public'), t("Check to block public access to all otherwise public personal pages on this site unless you are currently logged in.")),
713                 '$force_publish'        => array('publish_all', t("Force publish"), get_config('system','publish_all'), t("Check to force all profiles on this site to be listed in the site directory.")),
714                 '$global_directory'     => array('directory_submit_url', t("Global directory update URL"), get_config('system','directory_submit_url'), t("URL to update the global directory. If this is not set, the global directory is completely unavailable to the application.")),
715                 '$thread_allow'         => array('thread_allow', t("Allow threaded items"), get_config('system','thread_allow'), t("Allow infinite level threading for items on this site.")),
716                 '$newuser_private'      => array('newuser_private', t("Private posts by default for new users"), get_config('system','newuser_private'), t("Set default post permissions for all new members to the default privacy group rather than public.")),
717                 '$enotify_no_content'   => array('enotify_no_content', t("Don't include post content in email notifications"), get_config('system','enotify_no_content'), t("Don't include the content of a post/comment/private message/etc. in the email notifications that are sent out from this site, as a privacy measure.")),
718                 '$private_addons'       => array('private_addons', t("Disallow public access to addons listed in the apps menu."), get_config('config','private_addons'), t("Checking this box will restrict addons listed in the apps menu to members only.")),
719                 '$disable_embedded'     => array('disable_embedded', t("Don't embed private images in posts"), get_config('system','disable_embedded'), t("Don't replace locally-hosted private photos in posts with an embedded copy of the image. This means that contacts who receive posts containing private photos will have to authenticate and load each image, which may take a while.")),
720                 '$allow_users_remote_self'      => array('allow_users_remote_self', t('Allow Users to set remote_self'), get_config('system','allow_users_remote_self'), t('With checking this, every user is allowed to mark every contact as a remote_self in the repair contact dialog. Setting this flag on a contact causes mirroring every posting of that contact in the users stream.')),
721                 '$no_multi_reg'         => array('no_multi_reg', t("Block multiple registrations"),  get_config('system','block_extended_register'), t("Disallow users to register additional accounts for use as pages.")),
722                 '$no_openid'            => array('no_openid', t("OpenID support"), !get_config('system','no_openid'), t("OpenID support for registration and logins.")),
723                 '$no_regfullname'       => array('no_regfullname', t("Fullname check"), !get_config('system','no_regfullname'), t("Force users to register with a space between firstname and lastname in Full name, as an antispam measure")),
724                 '$no_utf'               => array('no_utf', t("UTF-8 Regular expressions"), !get_config('system','no_utf'), t("Use PHP UTF8 regular expressions")),
725                 '$community_page_style' => array('community_page_style', t("Community Page Style"), get_config('system','community_page_style'), t("Type of community page to show. 'Global community' shows every public posting from an open distributed network that arrived on this server."), $community_page_style_choices),
726                 '$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')")),
727                 '$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.")),
728                 '$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),
729                 '$diaspora_enabled'     => array('diaspora_enabled', t("Enable Diaspora support"), get_config('system','diaspora_enabled'), t("Provide built-in Diaspora network compatibility.")),
730                 '$dfrn_only'            => array('dfrn_only', t('Only allow Friendica contacts'), get_config('system','dfrn_only'), t("All contacts must use Friendica protocols. All other built-in communication protocols disabled.")),
731                 '$verifyssl'            => array('verifyssl', t("Verify SSL"), get_config('system','verifyssl'), t("If you wish, you can turn on strict certificate checking. This will mean you cannot connect (at all) to self-signed SSL sites.")),
732                 '$proxyuser'            => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""),
733                 '$proxy'                => array('proxy', t("Proxy URL"), get_config('system','proxy'), ""),
734                 '$timeout'              => array('timeout', t("Network timeout"), (x(get_config('system','curl_timeout'))?get_config('system','curl_timeout'):60), t("Value is in seconds. Set to 0 for unlimited (not recommended).")),
735                 '$delivery_interval'    => array('delivery_interval', t("Delivery interval"), (x(get_config('system','delivery_interval'))?get_config('system','delivery_interval'):2), t("Delay background delivery processes by this many seconds to reduce system load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 for large dedicated servers.")),
736                 '$poll_interval'        => array('poll_interval', t("Poll interval"), (x(get_config('system','poll_interval'))?get_config('system','poll_interval'):2), t("Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval.")),
737                 '$maxloadavg'           => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")),
738                 '$maxloadavg_frontend'  => array('maxloadavg_frontend', t("Maximum Load Average (Frontend)"), ((intval(get_config('system','maxloadavg_frontend')) > 0)?get_config('system','maxloadavg_frontend'):50), t("Maximum system load before the frontend quits service - default 50.")),
739
740                 '$poco_completion'      => array('poco_completion', t("Periodical check of global contacts"), get_config('system','poco_completion'), t("If enabled, the global contacts are checked periodically for missing or outdated data and the vitality of the contacts and servers.")),
741                 '$poco_discovery'       => array('poco_discovery', t("Discover contacts from other servers"), (string) intval(get_config('system','poco_discovery')), t("Periodically query other servers for contacts. You can choose between 'users': the users on the remote system, 'Global Contacts': active contacts that are known on the system. The fallback is meant for Redmatrix servers and older friendica servers, where global contacts weren't available. The fallback increases the server load, so the recommened setting is 'Users, Global Contacts'."), $poco_discovery_choices),
742                 '$poco_discovery_since' => array('poco_discovery_since', t("Timeframe for fetching global contacts"), (string) intval(get_config('system','poco_discovery_since')), t("When the discovery is activated, this value defines the timeframe for the activity of the global contacts that are fetched from other servers."), $poco_discovery_since_choices),
743                 '$poco_local_search'    => array('poco_local_search', t("Search the local directory"), get_config('system','poco_local_search'), t("Search the local directory instead of the global directory. When searching locally, every search will be executed on the global directory in the background. This improves the search results when the search is repeated.")),
744
745                 '$use_fulltext_engine'  => array('use_fulltext_engine', t("Use MySQL full text engine"), get_config('system','use_fulltext_engine'), t("Activates the full text engine. Speeds up search - but can only search for four and more characters.")),
746                 '$suppress_language'    => array('suppress_language', t("Suppress Language"), get_config('system','suppress_language'), t("Suppress language information in meta information about a posting.")),
747                 '$suppress_tags'        => array('suppress_tags', t("Suppress Tags"), get_config('system','suppress_tags'), t("Suppress showing a list of hashtags at the end of the posting.")),
748                 '$itemcache'            => array('itemcache', t("Path to item cache"), get_config('system','itemcache'), "The item caches buffers generated bbcode and external images."),
749                 '$itemcache_duration'   => array('itemcache_duration', t("Cache duration in seconds"), get_config('system','itemcache_duration'), t("How long should the cache files be hold? Default value is 86400 seconds (One day). To disable the item cache, set the value to -1.")),
750                 '$max_comments'         => array('max_comments', t("Maximum numbers of comments per post"), get_config('system','max_comments'), t("How much comments should be shown for each post? Default value is 100.")),
751                 '$lockpath'             => array('lockpath', t("Path for lock file"), get_config('system','lockpath'), "The lock file is used to avoid multiple pollers at one time. Only define a folder here."),
752                 '$temppath'             => array('temppath', t("Temp path"), get_config('system','temppath'), "If you have a restricted system where the webserver can't access the system temp path, enter another path here."),
753                 '$basepath'             => array('basepath', t("Base path to installation"), get_config('system','basepath'), "If the system cannot detect the correct path to your installation, enter the correct path here. This setting should only be set if you are using a restricted system and symbolic links to your webroot."),
754                 '$proxy_disabled'       => array('proxy_disabled', t("Disable picture proxy"), get_config('system','proxy_disabled'), t("The picture proxy increases performance and privacy. It shouldn't be used on systems with very low bandwith.")),
755                 '$old_pager'            => array('old_pager', t("Enable old style pager"), get_config('system','old_pager'), t("The old style pager has page numbers but slows down massively the page speed.")),
756                 '$only_tag_search'      => array('only_tag_search', t("Only search in tags"), get_config('system','only_tag_search'), t("On large systems the text search can slow down the system extremely.")),
757
758                 '$relocate_url'     => array('relocate_url', t("New base url"), $a->get_baseurl(), "Change base url for this server. Sends relocate message to all DFRN contacts of all users."),
759                 
760                 '$rino'                 => array('rino', t("RINO Encryption"), intval(get_config('system','rino_encrypt')), t("Encryption layer between nodes."), array("Disabled", "RINO1 (deprecated)", "RINO2")),
761                 
762                 '$form_security_token' => get_form_security_token("admin_site")
763
764         ));
765
766 }
767
768
769 function admin_page_dbsync(&$a) {
770
771         $o = '';
772
773         if($a->argc > 3 && intval($a->argv[3]) && $a->argv[2] === 'mark') {
774                 set_config('database', 'update_' . intval($a->argv[3]), 'success');
775                 $curr = get_config('system','build');
776                 if(intval($curr) == intval($a->argv[3]))
777                         set_config('system','build',intval($curr) + 1);
778                 info( t('Update has been marked successful') . EOL);
779                 goaway($a->get_baseurl(true) . '/admin/dbsync');
780         }
781
782         if(($a->argc > 2) AND (intval($a->argv[2]) OR ($a->argv[2] === 'check'))) {
783                 require_once("include/dbstructure.php");
784                 $retval = update_structure(false, true);
785                 if (!$retval) {
786                         $o .= sprintf(t("Database structure update %s was successfully applied."), DB_UPDATE_VERSION)."<br />";
787                         set_config('database', 'dbupdate_'.DB_UPDATE_VERSION, 'success');
788                 } else
789                         $o .= sprintf(t("Executing of database structure update %s failed with error: %s"),
790                                         DB_UPDATE_VERSION, $retval)."<br />";
791                 if ($a->argv[2] === 'check')
792                         return $o;
793         }
794
795         if ($a->argc > 2 && intval($a->argv[2])) {
796                 require_once('update.php');
797                 $func = 'update_' . intval($a->argv[2]);
798                 if(function_exists($func)) {
799                         $retval = $func();
800                         if($retval === UPDATE_FAILED) {
801                                 $o .= sprintf(t("Executing %s failed with error: %s"), $func, $retval);
802                         }
803                         elseif($retval === UPDATE_SUCCESS) {
804                                 $o .= sprintf(t('Update %s was successfully applied.', $func));
805                                 set_config('database',$func, 'success');
806                         }
807                         else
808                                 $o .= sprintf(t('Update %s did not return a status. Unknown if it succeeded.'), $func);
809                 } else {
810                         $o .= sprintf(t('There was no additional update function %s that needed to be called.'), $func)."<br />";
811                         set_config('database',$func, 'success');
812                 }
813                 return $o;
814         }
815
816         $failed = array();
817         $r = q("select k, v from config where `cat` = 'database' ");
818         if(count($r)) {
819                 foreach($r as $rr) {
820                         $upd = intval(substr($rr['k'],7));
821                         if($upd < 1139 || $rr['v'] === 'success')
822                                 continue;
823                         $failed[] = $upd;
824                 }
825         }
826         if(! count($failed)) {
827                 $o = replace_macros(get_markup_template('structure_check.tpl'),array(
828                         '$base' => $a->get_baseurl(true),
829                         '$banner' => t('No failed updates.'),
830                         '$check' => t('Check database structure'),
831                 ));
832         } else {
833                 $o = replace_macros(get_markup_template('failed_updates.tpl'),array(
834                         '$base' => $a->get_baseurl(true),
835                         '$banner' => t('Failed Updates'),
836                         '$desc' => t('This does not include updates prior to 1139, which did not return a status.'),
837                         '$mark' => t('Mark success (if update was manually applied)'),
838                         '$apply' => t('Attempt to execute this update step automatically'),
839                         '$failed' => $failed
840                 ));
841         }
842
843         return $o;
844
845 }
846
847 /**
848  * Users admin page
849  *
850  * @param App $a
851  */
852 function admin_page_users_post(&$a){
853         $pending = ( x($_POST, 'pending') ? $_POST['pending'] : Array() );
854         $users = ( x($_POST, 'user') ? $_POST['user'] : Array() );
855         $nu_name = ( x($_POST, 'new_user_name') ? $_POST['new_user_name'] : '');
856         $nu_nickname = ( x($_POST, 'new_user_nickname') ? $_POST['new_user_nickname'] : '');
857         $nu_email = ( x($_POST, 'new_user_email') ? $_POST['new_user_email'] : '');
858
859         check_form_security_token_redirectOnErr($a->get_baseurl().'/admin/users', 'admin_users');
860
861         if (!($nu_name==="") && !($nu_email==="") && !($nu_nickname==="")) {
862                 require_once('include/user.php');
863
864                 $result = create_user( array('username'=>$nu_name, 'email'=>$nu_email, 'nickname'=>$nu_nickname, 'verified'=>1)  );
865                 if(! $result['success']) {
866                         notice($result['message']);
867                         return;
868                 }
869                 $nu = $result['user'];
870                 $preamble = deindent(t('
871                         Dear %1$s,
872                                 the administrator of %2$s has set up an account for you.'));
873                 $body = deindent(t('
874                         The login details are as follows:
875
876                         Site Location:  %1$s
877                         Login Name:             %2$s
878                         Password:               %3$s
879
880                         You may change your password from your account "Settings" page after logging
881                         in.
882
883                         Please take a few moments to review the other account settings on that page.
884
885                         You may also wish to add some basic information to your default profile
886                         (on the "Profiles" page) so that other people can easily find you.
887
888                         We recommend setting your full name, adding a profile photo,
889                         adding some profile "keywords" (very useful in making new friends) - and
890                         perhaps what country you live in; if you do not wish to be more specific
891                         than that.
892
893                         We fully respect your right to privacy, and none of these items are necessary.
894                         If you are new and do not know anybody here, they may help
895                         you to make some new and interesting friends.
896
897                         Thank you and welcome to %4$s.'));
898
899                 $preamble = sprintf($preamble, $nu['username'], $a->config['sitename']);
900                 $body = sprintf($body, $a->get_baseurl(), $nu['email'], $result['password'], $a->config['sitename']);
901
902                 notification(array(
903                         'type' => "SYSTEM_EMAIL",
904                         'to_email' => $nu['email'],
905                         'subject'=> sprintf( t('Registration details for %s'), $a->config['sitename']),
906                         'preamble'=> $preamble,
907                         'body' => $body));
908
909         }
910
911         if (x($_POST,'page_users_block')){
912                 foreach($users as $uid){
913                         q("UPDATE `user` SET `blocked`=1-`blocked` WHERE `uid`=%s",
914                                 intval( $uid )
915                         );
916                 }
917                 notice( sprintf( tt("%s user blocked/unblocked", "%s users blocked/unblocked", count($users)), count($users)) );
918         }
919         if (x($_POST,'page_users_delete')){
920                 require_once("include/Contact.php");
921                 foreach($users as $uid){
922                         user_remove($uid);
923                 }
924                 notice( sprintf( tt("%s user deleted", "%s users deleted", count($users)), count($users)) );
925         }
926
927         if (x($_POST,'page_users_approve')){
928                 require_once("mod/regmod.php");
929                 foreach($pending as $hash){
930                         user_allow($hash);
931                 }
932         }
933         if (x($_POST,'page_users_deny')){
934                 require_once("mod/regmod.php");
935                 foreach($pending as $hash){
936                         user_deny($hash);
937                 }
938         }
939         goaway($a->get_baseurl(true) . '/admin/users' );
940         return; // NOTREACHED
941 }
942
943 /**
944  * @param App $a
945  * @return string
946  */
947 function admin_page_users(&$a){
948         if ($a->argc>2) {
949                 $uid = $a->argv[3];
950                 $user = q("SELECT username, blocked FROM `user` WHERE `uid`=%d", intval($uid));
951                 if (count($user)==0){
952                         notice( 'User not found' . EOL);
953                         goaway($a->get_baseurl(true) . '/admin/users' );
954                         return ''; // NOTREACHED
955                 }
956                 switch($a->argv[2]){
957                         case "delete":{
958                                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
959                                 // delete user
960                                 require_once("include/Contact.php");
961                                 user_remove($uid);
962
963                                 notice( sprintf(t("User '%s' deleted"), $user[0]['username']) . EOL);
964                         }; break;
965                         case "block":{
966                                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
967                                 q("UPDATE `user` SET `blocked`=%d WHERE `uid`=%s",
968                                         intval( 1-$user[0]['blocked'] ),
969                                         intval( $uid )
970                                 );
971                                 notice( sprintf( ($user[0]['blocked']?t("User '%s' unblocked"):t("User '%s' blocked")) , $user[0]['username']) . EOL);
972                         }; break;
973                 }
974                 goaway($a->get_baseurl(true) . '/admin/users' );
975                 return ''; // NOTREACHED
976
977         }
978
979         /* get pending */
980         $pending = q("SELECT `register`.*, `contact`.`name`, `user`.`email`
981                                  FROM `register`
982                                  LEFT JOIN `contact` ON `register`.`uid` = `contact`.`uid`
983                                  LEFT JOIN `user` ON `register`.`uid` = `user`.`uid`;");
984
985
986         /* get users */
987
988         $total = q("SELECT count(*) as total FROM `user` where 1");
989         if(count($total)) {
990                 $a->set_pager_total($total[0]['total']);
991                 $a->set_pager_itemspage(100);
992         }
993
994
995         $users = q("SELECT `user` . * , `contact`.`name` , `contact`.`url` , `contact`.`micro`, `lastitem`.`lastitem_date`, `user`.`account_expired`
996                                 FROM
997                                         (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid`
998                                         FROM `item`
999                                         WHERE `item`.`type` = 'wall'
1000                                         GROUP BY `item`.`uid`) AS `lastitem`
1001                                                  RIGHT OUTER JOIN `user` ON `user`.`uid` = `lastitem`.`uid`,
1002                                            `contact`
1003                                 WHERE
1004                                            `user`.`uid` = `contact`.`uid`
1005                                                 AND `user`.`verified` =1
1006                                         AND `contact`.`self` =1
1007                                 ORDER BY `contact`.`name` LIMIT %d, %d
1008                                 ",
1009                                 intval($a->pager['start']),
1010                                 intval($a->pager['itemspage'])
1011                                 );
1012
1013         $adminlist = explode(",", str_replace(" ", "", $a->config['admin_email']));
1014         $_setup_users = function ($e) use ($adminlist){
1015                 $accounts = Array(
1016                         t('Normal Account'),
1017                         t('Soapbox Account'),
1018                         t('Community/Celebrity Account'),
1019                                                 t('Automatic Friend Account')
1020                 );
1021                 $e['page-flags'] = $accounts[$e['page-flags']];
1022                 $e['register_date'] = relative_date($e['register_date']);
1023                 $e['login_date'] = relative_date($e['login_date']);
1024                 $e['lastitem_date'] = relative_date($e['lastitem_date']);
1025                 //$e['is_admin'] = ($e['email'] === $a->config['admin_email']);
1026                 $e['is_admin'] = in_array($e['email'], $adminlist);
1027                 $e['is_deletable'] = (intval($e['uid']) != local_user());
1028                 $e['deleted'] = ($e['account_removed']?relative_date($e['account_expires_on']):False);
1029                 return $e;
1030         };
1031         $users = array_map($_setup_users, $users);
1032
1033
1034         // Get rid of dashes in key names, Smarty3 can't handle them
1035         // and extracting deleted users
1036
1037         $tmp_users = Array();
1038         $deleted = Array();
1039
1040         while(count($users)) {
1041                 $new_user = Array();
1042                 foreach( array_pop($users) as $k => $v) {
1043                         $k = str_replace('-','_',$k);
1044                         $new_user[$k] = $v;
1045                 }
1046                 if($new_user['deleted']) {
1047                         array_push($deleted, $new_user);
1048                 }
1049                 else {
1050                         array_push($tmp_users, $new_user);
1051                 }
1052         }
1053         //Reversing the two array, and moving $tmp_users to $users
1054         array_reverse($deleted);
1055         while(count($tmp_users)) {
1056                 array_push($users, array_pop($tmp_users));
1057         }
1058
1059         $t = get_markup_template("admin_users.tpl");
1060         $o = replace_macros($t, array(
1061                 // strings //
1062                 '$title' => t('Administration'),
1063                 '$page' => t('Users'),
1064                 '$submit' => t('Add User'),
1065                 '$select_all' => t('select all'),
1066                 '$h_pending' => t('User registrations waiting for confirm'),
1067                 '$h_deleted' => t('User waiting for permanent deletion'),
1068                 '$th_pending' => array( t('Request date'), t('Name'), t('Email') ),
1069                 '$no_pending' =>  t('No registrations.'),
1070                 '$approve' => t('Approve'),
1071                 '$deny' => t('Deny'),
1072                 '$delete' => t('Delete'),
1073                 '$block' => t('Block'),
1074                 '$unblock' => t('Unblock'),
1075                 '$siteadmin' => t('Site admin'),
1076                 '$accountexpired' => t('Account expired'),
1077
1078                 '$h_users' => t('Users'),
1079                 '$h_newuser' => t('New User'),
1080                 '$th_deleted' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'), t('Deleted since') ),
1081                 '$th_users' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'),  t('Account') ),
1082
1083                 '$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?'),
1084                 '$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?'),
1085
1086                 '$form_security_token' => get_form_security_token("admin_users"),
1087
1088                 // values //
1089                 '$baseurl' => $a->get_baseurl(true),
1090
1091                 '$pending' => $pending,
1092                 'deleted' => $deleted,
1093                 '$users' => $users,
1094                 '$newusername'  => array('new_user_name', t("Name"), '', t("Name of the new user.")),
1095                 '$newusernickname'  => array('new_user_nickname', t("Nickname"), '', t("Nickname of the new user.")),
1096                 '$newuseremail'  => array('new_user_email', t("Email"), '', t("Email address of the new user."), '', '', 'email'),
1097         ));
1098         $o .= paginate($a);
1099         return $o;
1100 }
1101
1102
1103 /**
1104  * Plugins admin page
1105  *
1106  * @param App $a
1107  * @return string
1108  */
1109 function admin_page_plugins(&$a){
1110
1111         /**
1112          * Single plugin
1113          */
1114         if ($a->argc == 3){
1115                 $plugin = $a->argv[2];
1116                 if (!is_file("addon/$plugin/$plugin.php")){
1117                         notice( t("Item not found.") );
1118                         return '';
1119                 }
1120
1121                 if (x($_GET,"a") && $_GET['a']=="t"){
1122                         check_form_security_token_redirectOnErr('/admin/plugins', 'admin_themes', 't');
1123
1124                         // Toggle plugin status
1125                         $idx = array_search($plugin, $a->plugins);
1126                         if ($idx !== false){
1127                                 unset($a->plugins[$idx]);
1128                                 uninstall_plugin($plugin);
1129                                 info( sprintf( t("Plugin %s disabled."), $plugin ) );
1130                         } else {
1131                                 $a->plugins[] = $plugin;
1132                                 install_plugin($plugin);
1133                                 info( sprintf( t("Plugin %s enabled."), $plugin ) );
1134                         }
1135                         set_config("system","addon", implode(", ",$a->plugins));
1136                         goaway($a->get_baseurl(true) . '/admin/plugins' );
1137                         return ''; // NOTREACHED
1138                 }
1139                 // display plugin details
1140                 require_once('library/markdown.php');
1141
1142                 if (in_array($plugin, $a->plugins)){
1143                         $status="on"; $action= t("Disable");
1144                 } else {
1145                         $status="off"; $action= t("Enable");
1146                 }
1147
1148                 $readme=Null;
1149                 if (is_file("addon/$plugin/README.md")){
1150                         $readme = file_get_contents("addon/$plugin/README.md");
1151                         $readme = Markdown($readme);
1152                 } else if (is_file("addon/$plugin/README")){
1153                         $readme = "<pre>". file_get_contents("addon/$plugin/README") ."</pre>";
1154                 }
1155
1156                 $admin_form="";
1157                 if (is_array($a->plugins_admin) && in_array($plugin, $a->plugins_admin)){
1158                         @require_once("addon/$plugin/$plugin.php");
1159                         $func = $plugin.'_plugin_admin';
1160                         $func($a, $admin_form);
1161                 }
1162
1163                 $t = get_markup_template("admin_plugins_details.tpl");
1164
1165                 return replace_macros($t, array(
1166                         '$title' => t('Administration'),
1167                         '$page' => t('Plugins'),
1168                         '$toggle' => t('Toggle'),
1169                         '$settings' => t('Settings'),
1170                         '$baseurl' => $a->get_baseurl(true),
1171
1172                         '$plugin' => $plugin,
1173                         '$status' => $status,
1174                         '$action' => $action,
1175                         '$info' => get_plugin_info($plugin),
1176                         '$str_author' => t('Author: '),
1177                         '$str_maintainer' => t('Maintainer: '),
1178
1179                         '$admin_form' => $admin_form,
1180                         '$function' => 'plugins',
1181                         '$screenshot' => '',
1182                         '$readme' => $readme,
1183
1184                         '$form_security_token' => get_form_security_token("admin_themes"),
1185                 ));
1186         }
1187
1188
1189
1190         /**
1191          * List plugins
1192          */
1193
1194         $plugins = array();
1195         $files = glob("addon/*/"); /* */
1196         if($files) {
1197                 foreach($files as $file) {
1198                         if (is_dir($file)){
1199                                 list($tmp, $id)=array_map("trim", explode("/",$file));
1200                                 $info = get_plugin_info($id);
1201                                 $show_plugin = true;
1202
1203                                 // If the addon is unsupported, then only show it, when it is enabled
1204                                 if ((strtolower($info["status"]) == "unsupported") AND !in_array($id,  $a->plugins))
1205                                         $show_plugin = false;
1206
1207                                 // Override the above szenario, when the admin really wants to see outdated stuff
1208                                 if (get_config("system", "show_unsupported_addons"))
1209                                         $show_plugin = true;
1210
1211                                 if ($show_plugin)
1212                                         $plugins[] = array($id, (in_array($id,  $a->plugins)?"on":"off") , $info);
1213                         }
1214                 }
1215         }
1216
1217         $t = get_markup_template("admin_plugins.tpl");
1218         return replace_macros($t, array(
1219                 '$title' => t('Administration'),
1220                 '$page' => t('Plugins'),
1221                 '$submit' => t('Save Settings'),
1222                 '$baseurl' => $a->get_baseurl(true),
1223                 '$function' => 'plugins',
1224                 '$plugins' => $plugins,
1225                 '$form_security_token' => get_form_security_token("admin_themes"),
1226         ));
1227 }
1228
1229 /**
1230  * @param array $themes
1231  * @param string $th
1232  * @param int $result
1233  */
1234 function toggle_theme(&$themes,$th,&$result) {
1235         for($x = 0; $x < count($themes); $x ++) {
1236                 if($themes[$x]['name'] === $th) {
1237                         if($themes[$x]['allowed']) {
1238                                 $themes[$x]['allowed'] = 0;
1239                                 $result = 0;
1240                         }
1241                         else {
1242                                 $themes[$x]['allowed'] = 1;
1243                                 $result = 1;
1244                         }
1245                 }
1246         }
1247 }
1248
1249 /**
1250  * @param array $themes
1251  * @param string $th
1252  * @return int
1253  */
1254 function theme_status($themes,$th) {
1255         for($x = 0; $x < count($themes); $x ++) {
1256                 if($themes[$x]['name'] === $th) {
1257                         if($themes[$x]['allowed']) {
1258                                 return 1;
1259                         }
1260                         else {
1261                                 return 0;
1262                         }
1263                 }
1264         }
1265         return 0;
1266 }
1267
1268
1269 /**
1270  * @param array $themes
1271  * @return string
1272  */
1273 function rebuild_theme_table($themes) {
1274         $o = '';
1275         if(count($themes)) {
1276                 foreach($themes as $th) {
1277                         if($th['allowed']) {
1278                                 if(strlen($o))
1279                                         $o .= ',';
1280                                 $o .= $th['name'];
1281                         }
1282                 }
1283         }
1284         return $o;
1285 }
1286
1287
1288 /**
1289  * Themes admin page
1290  *
1291  * @param App $a
1292  * @return string
1293  */
1294 function admin_page_themes(&$a){
1295
1296         $allowed_themes_str = get_config('system','allowed_themes');
1297         $allowed_themes_raw = explode(',',$allowed_themes_str);
1298         $allowed_themes = array();
1299         if(count($allowed_themes_raw))
1300                 foreach($allowed_themes_raw as $x)
1301                         if(strlen(trim($x)))
1302                                 $allowed_themes[] = trim($x);
1303
1304         $themes = array();
1305         $files = glob('view/theme/*'); /* */
1306         if($files) {
1307                 foreach($files as $file) {
1308                         $f = basename($file);
1309                         $is_experimental = intval(file_exists($file . '/experimental'));
1310                         $is_supported = 1-(intval(file_exists($file . '/unsupported')));
1311                         $is_allowed = intval(in_array($f,$allowed_themes));
1312
1313                         if ($is_allowed OR $is_supported OR get_config("system", "show_unsupported_themes"))
1314                                 $themes[] = array('name' => $f, 'experimental' => $is_experimental, 'supported' => $is_supported, 'allowed' => $is_allowed);
1315                 }
1316         }
1317
1318         if(! count($themes)) {
1319                 notice( t('No themes found.'));
1320                 return '';
1321         }
1322
1323         /**
1324          * Single theme
1325          */
1326
1327         if ($a->argc == 3){
1328                 $theme = $a->argv[2];
1329                 if(! is_dir("view/theme/$theme")){
1330                         notice( t("Item not found.") );
1331                         return '';
1332                 }
1333
1334                 if (x($_GET,"a") && $_GET['a']=="t"){
1335                         check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't');
1336
1337                         // Toggle theme status
1338
1339                         toggle_theme($themes,$theme,$result);
1340                         $s = rebuild_theme_table($themes);
1341                         if($result) {
1342                                 install_theme($theme);
1343                                 info( sprintf('Theme %s enabled.',$theme));
1344                         }
1345                         else {
1346                                 uninstall_theme($theme);
1347                                 info( sprintf('Theme %s disabled.',$theme));
1348                         }
1349
1350                         set_config('system','allowed_themes',$s);
1351                         goaway($a->get_baseurl(true) . '/admin/themes' );
1352                         return ''; // NOTREACHED
1353                 }
1354
1355                 // display theme details
1356                 require_once('library/markdown.php');
1357
1358                 if (theme_status($themes,$theme)) {
1359                         $status="on"; $action= t("Disable");
1360                 } else {
1361                         $status="off"; $action= t("Enable");
1362                 }
1363
1364                 $readme=Null;
1365                 if (is_file("view/theme/$theme/README.md")){
1366                         $readme = file_get_contents("view/theme/$theme/README.md");
1367                         $readme = Markdown($readme);
1368                 } else if (is_file("view/theme/$theme/README")){
1369                         $readme = "<pre>". file_get_contents("view/theme/$theme/README") ."</pre>";
1370                 }
1371
1372                 $admin_form="";
1373                 if (is_file("view/theme/$theme/config.php")){
1374                         require_once("view/theme/$theme/config.php");
1375                         if(function_exists("theme_admin")){
1376                                 $admin_form = theme_admin($a);
1377                         }
1378
1379                 }
1380
1381                 $screenshot = array( get_theme_screenshot($theme), t('Screenshot'));
1382                 if(! stristr($screenshot[0],$theme))
1383                         $screenshot = null;
1384
1385                 $t = get_markup_template("admin_plugins_details.tpl");
1386                 return replace_macros($t, array(
1387                         '$title' => t('Administration'),
1388                         '$page' => t('Themes'),
1389                         '$toggle' => t('Toggle'),
1390                         '$settings' => t('Settings'),
1391                         '$baseurl' => $a->get_baseurl(true),
1392
1393                         '$plugin' => $theme,
1394                         '$status' => $status,
1395                         '$action' => $action,
1396                         '$info' => get_theme_info($theme),
1397                         '$function' => 'themes',
1398                         '$admin_form' => $admin_form,
1399                         '$str_author' => t('Author: '),
1400                         '$str_maintainer' => t('Maintainer: '),
1401                         '$screenshot' => $screenshot,
1402                         '$readme' => $readme,
1403
1404                         '$form_security_token' => get_form_security_token("admin_themes"),
1405                 ));
1406         }
1407
1408         /**
1409          * List themes
1410          */
1411
1412         $xthemes = array();
1413         if($themes) {
1414                 foreach($themes as $th) {
1415                         $xthemes[] = array($th['name'],(($th['allowed']) ? "on" : "off"), get_theme_info($th['name']));
1416                 }
1417         }
1418
1419         $t = get_markup_template("admin_plugins.tpl");
1420         return replace_macros($t, array(
1421                 '$title' => t('Administration'),
1422                 '$page' => t('Themes'),
1423                 '$submit' => t('Save Settings'),
1424                 '$baseurl' => $a->get_baseurl(true),
1425                 '$function' => 'themes',
1426                 '$plugins' => $xthemes,
1427                 '$experimental' => t('[Experimental]'),
1428                 '$unsupported' => t('[Unsupported]'),
1429                 '$form_security_token' => get_form_security_token("admin_themes"),
1430         ));
1431 }
1432
1433
1434 /**
1435  * Logs admin page
1436  *
1437  * @param App $a
1438  */
1439
1440 function admin_page_logs_post(&$a) {
1441         if (x($_POST,"page_logs")) {
1442                 check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
1443
1444                 $logfile                =       ((x($_POST,'logfile'))          ? notags(trim($_POST['logfile']))       : '');
1445                 $debugging              =       ((x($_POST,'debugging'))        ? true                                                          : false);
1446                 $loglevel               =       ((x($_POST,'loglevel'))         ? intval(trim($_POST['loglevel']))      : 0);
1447
1448                 set_config('system','logfile', $logfile);
1449                 set_config('system','debugging',  $debugging);
1450                 set_config('system','loglevel', $loglevel);
1451
1452
1453         }
1454
1455         info( t("Log settings updated.") );
1456         goaway($a->get_baseurl(true) . '/admin/logs' );
1457         return; // NOTREACHED
1458 }
1459
1460 /**
1461  * @param App $a
1462  * @return string
1463  */
1464 function admin_page_logs(&$a){
1465
1466         $log_choices = Array(
1467                 LOGGER_NORMAL => 'Normal',
1468                 LOGGER_TRACE => 'Trace',
1469                 LOGGER_DEBUG => 'Debug',
1470                 LOGGER_DATA => 'Data',
1471                 LOGGER_ALL => 'All'
1472         );
1473
1474         $t = get_markup_template("admin_logs.tpl");
1475
1476         $f = get_config('system','logfile');
1477
1478         $data = '';
1479
1480         if(!file_exists($f)) {
1481                 $data = t("Error trying to open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f exist and is
1482 readable.");
1483         }
1484         else {
1485                 $fp = fopen($f, 'r');
1486                 if(!$fp) {
1487                         $data = t("Couldn't open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f is readable.");
1488                 }
1489                 else {
1490                         $fstat = fstat($fp);
1491                         $size = $fstat['size'];
1492                         if($size != 0)
1493                         {
1494                                 if($size > 5000000 || $size < 0)
1495                                         $size = 5000000;
1496                                 $seek = fseek($fp,0-$size,SEEK_END);
1497                                 if($seek === 0) {
1498                                         $data = escape_tags(fread($fp,$size));
1499                                         while(! feof($fp))
1500                                                 $data .= escape_tags(fread($fp,4096));
1501                                 }
1502                         }
1503                         fclose($fp);
1504                 }
1505         }
1506
1507         return replace_macros($t, array(
1508                 '$title' => t('Administration'),
1509                 '$page' => t('Logs'),
1510                 '$submit' => t('Save Settings'),
1511                 '$clear' => t('Clear'),
1512                 '$data' => $data,
1513                 '$baseurl' => $a->get_baseurl(true),
1514                 '$logname' =>  get_config('system','logfile'),
1515
1516                                                                         // name, label, value, help string, extra data...
1517                 '$debugging'            => array('debugging', t("Enable Debugging"),get_config('system','debugging'), ""),
1518                 '$logfile'                      => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Friendica top-level directory.")),
1519                 '$loglevel'             => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices),
1520
1521                 '$form_security_token' => get_form_security_token("admin_logs"),
1522         ));
1523 }
1524
1525 /**
1526  * @param App $a
1527  */
1528 function admin_page_remoteupdate_post(&$a) {
1529         // this function should be called via ajax post
1530         if(!is_site_admin()) {
1531                 return;
1532         }
1533
1534
1535         if (x($_POST,'remotefile') && $_POST['remotefile']!=""){
1536                 $remotefile = $_POST['remotefile'];
1537                 $ftpdata = (x($_POST['ftphost'])?$_POST:false);
1538                 doUpdate($remotefile, $ftpdata);
1539         } else {
1540                 echo "No remote file to download. Abort!";
1541         }
1542
1543         killme();
1544 }
1545
1546 /**
1547  * @param App $a
1548  * @return string
1549  */
1550 function admin_page_remoteupdate(&$a) {
1551         if(!is_site_admin()) {
1552                 return login(false);
1553         }
1554
1555         $canwrite = canWeWrite();
1556         $canftp = function_exists('ftp_connect');
1557
1558         $needupdate = true;
1559         $u = checkUpdate();
1560         if (!is_array($u)){
1561                 $needupdate = false;
1562                 $u = array('','','');
1563         }
1564
1565         $tpl = get_markup_template("admin_remoteupdate.tpl");
1566         return replace_macros($tpl, array(
1567                 '$baseurl' => $a->get_baseurl(true),
1568                 '$submit' => t("Update now"),
1569                 '$close' => t("Close"),
1570                 '$localversion' => FRIENDICA_VERSION,
1571                 '$remoteversion' => $u[1],
1572                 '$needupdate' => $needupdate,
1573                 '$canwrite' => $canwrite,
1574                 '$canftp'       => $canftp,
1575                 '$ftphost'      => array('ftphost', t("FTP Host"), '',''),
1576                 '$ftppath'      => array('ftppath', t("FTP Path"), '/',''),
1577                 '$ftpuser'      => array('ftpuser', t("FTP User"), '',''),
1578                 '$ftppwd'       => array('ftppwd', t("FTP Password"), '',''),
1579                 '$remotefile'=>array('remotefile','', $u['2'],''),
1580         ));
1581
1582 }