]> git.mxchange.org Git - friendica.git/blob - mod/admin.php
Merge remote-tracking branch 'upstream/develop' into 1509-diaspora-import
[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                 '$baseurl' => $a->get_baseurl(),
257                 '$platform' => FRIENDICA_PLATFORM,
258                 '$codename' => FRIENDICA_CODENAME,
259                 '$build' =>  get_config('system','build'),
260                 '$plugins' => Array( t('Active plugins'), $a->plugins )
261         ));
262 }
263
264
265 /**
266  * Admin Site Page
267  *  @param App $a
268  */
269 function admin_page_site_post(&$a){
270         if (!x($_POST,"page_site")){
271                 return;
272         }
273
274         check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
275
276         // relocate
277         if (x($_POST,'relocate') && x($_POST,'relocate_url') && $_POST['relocate_url']!=""){
278                 $new_url = $_POST['relocate_url'];
279                 $new_url = rtrim($new_url,"/");
280
281                 $parsed = @parse_url($new_url);
282                 if (!$parsed || (!x($parsed,'host') || !x($parsed,'scheme'))) {
283                         notice(t("Can not parse base url. Must have at least <scheme>://<domain>"));
284                         goaway($a->get_baseurl(true) . '/admin/site' );
285                 }
286
287                 /* steps:
288                  * replace all "baseurl" to "new_url" in config, profile, term, items and contacts
289                  * send relocate for every local user
290                  * */
291
292                 $old_url = $a->get_baseurl(true);
293
294                 function update_table($table_name, $fields, $old_url, $new_url) {
295                         global $db, $a;
296
297                         $dbold = dbesc($old_url);
298                         $dbnew = dbesc($new_url);
299
300                         $upd = array();
301                         foreach ($fields as $f) {
302                                 $upd[] = "`$f` = REPLACE(`$f`, '$dbold', '$dbnew')";
303                         }
304
305                         $upds = implode(", ", $upd);
306
307
308
309                         $q = sprintf("UPDATE %s SET %s;", $table_name, $upds);
310                         $r = q($q);
311                         if (!$r) {
312                                 notice( "Failed updating '$table_name': " . $db->error );
313                                 goaway($a->get_baseurl(true) . '/admin/site' );
314                         }
315                 }
316
317                 // update tables
318                 update_table("profile", array('photo', 'thumb'), $old_url, $new_url);
319                 update_table("term", array('url'), $old_url, $new_url);
320                 update_table("contact", array('photo','thumb','micro','url','nurl','request','notify','poll','confirm','poco'), $old_url, $new_url);
321                 update_table("unique_contacts", array('url'), $old_url, $new_url);
322                 update_table("item", array('owner-link','owner-avatar','author-name','author-link','author-avatar','body','plink','tag'), $old_url, $new_url);
323
324                 // update config
325                 $a->set_baseurl($new_url);
326                 set_config('system','url',$new_url);
327
328                 // send relocate
329                 $users = q("SELECT uid FROM user WHERE account_removed = 0 AND account_expired = 0");
330
331                 foreach ($users as $user) {
332                         proc_run('php', 'include/notifier.php', 'relocate', $user['uid']);
333                 }
334
335                 info("Relocation started. Could take a while to complete.");
336
337                 goaway($a->get_baseurl(true) . '/admin/site' );
338         }
339         // end relocate
340
341         $sitename               =       ((x($_POST,'sitename'))                 ? notags(trim($_POST['sitename']))              : '');
342         $hostname               =       ((x($_POST,'hostname'))                 ? notags(trim($_POST['hostname']))              : '');
343         $sender_email           =       ((x($_POST,'sender_email'))             ? notags(trim($_POST['sender_email']))          : '');
344         $banner                 =       ((x($_POST,'banner'))                   ? trim($_POST['banner'])                        : false);
345         $shortcut_icon          =       ((x($_POST,'shortcut_icon'))            ? notags(trim($_POST['shortcut_icon']))         : '');
346         $touch_icon             =       ((x($_POST,'touch_icon'))               ? notags(trim($_POST['touch_icon']))            : '');
347         $info                   =       ((x($_POST,'info'))                     ? trim($_POST['info'])                  : false);
348         $language               =       ((x($_POST,'language'))                 ? notags(trim($_POST['language']))              : '');
349         $theme                  =       ((x($_POST,'theme'))                    ? notags(trim($_POST['theme']))                 : '');
350         $theme_mobile           =       ((x($_POST,'theme_mobile'))             ? notags(trim($_POST['theme_mobile']))          : '');
351         $maximagesize           =       ((x($_POST,'maximagesize'))             ? intval(trim($_POST['maximagesize']))          :  0);
352         $maximagelength         =       ((x($_POST,'maximagelength'))           ? intval(trim($_POST['maximagelength']))        :  MAX_IMAGE_LENGTH);
353         $jpegimagequality       =       ((x($_POST,'jpegimagequality'))         ? intval(trim($_POST['jpegimagequality']))      :  JPEG_QUALITY);
354
355
356         $register_policy        =       ((x($_POST,'register_policy'))          ? intval(trim($_POST['register_policy']))       :  0);
357         $daily_registrations    =       ((x($_POST,'max_daily_registrations'))  ? intval(trim($_POST['max_daily_registrations']))       :0);
358         $abandon_days           =       ((x($_POST,'abandon_days'))             ? intval(trim($_POST['abandon_days']))          :  0);
359
360         $register_text          =       ((x($_POST,'register_text'))            ? notags(trim($_POST['register_text']))         : '');
361
362         $allowed_sites          =       ((x($_POST,'allowed_sites'))            ? notags(trim($_POST['allowed_sites']))         : '');
363         $allowed_email          =       ((x($_POST,'allowed_email'))            ? notags(trim($_POST['allowed_email']))         : '');
364         $block_public           =       ((x($_POST,'block_public'))             ? True                                          : False);
365         $force_publish          =       ((x($_POST,'publish_all'))              ? True                                          : False);
366         $global_directory       =       ((x($_POST,'directory_submit_url'))     ? notags(trim($_POST['directory_submit_url']))  : '');
367         $thread_allow           =       ((x($_POST,'thread_allow'))             ? True                                          : False);
368         $newuser_private                =       ((x($_POST,'newuser_private'))          ? True                                          : False);
369         $enotify_no_content             =       ((x($_POST,'enotify_no_content'))       ? True                                          : False);
370         $private_addons                 =       ((x($_POST,'private_addons'))           ? True                                          : False);
371         $disable_embedded               =       ((x($_POST,'disable_embedded'))         ? True                                          : False);
372         $allow_users_remote_self        =       ((x($_POST,'allow_users_remote_self'))          ? True                                          : False);
373
374         $no_multi_reg           =       ((x($_POST,'no_multi_reg'))             ? True                                          : False);
375         $no_openid              =       !((x($_POST,'no_openid'))               ? True                                          : False);
376         $no_regfullname         =       !((x($_POST,'no_regfullname'))          ? True                                          : False);
377         $no_utf                 =       !((x($_POST,'no_utf'))                  ? True                                          : False);
378         $community_page_style   =       ((x($_POST,'community_page_style'))     ? intval(trim($_POST['community_page_style']))  : 0);
379         $max_author_posts_community_page        =       ((x($_POST,'max_author_posts_community_page'))  ? intval(trim($_POST['max_author_posts_community_page']))       : 0);
380
381         $verifyssl              =       ((x($_POST,'verifyssl'))                ? True                                          : False);
382         $proxyuser              =       ((x($_POST,'proxyuser'))                ? notags(trim($_POST['proxyuser']))             : '');
383         $proxy                  =       ((x($_POST,'proxy'))                    ? notags(trim($_POST['proxy']))                 : '');
384         $timeout                =       ((x($_POST,'timeout'))                  ? intval(trim($_POST['timeout']))               : 60);
385         $delivery_interval      =       ((x($_POST,'delivery_interval'))        ? intval(trim($_POST['delivery_interval']))     : 0);
386         $poll_interval          =       ((x($_POST,'poll_interval'))            ? intval(trim($_POST['poll_interval']))         : 0);
387         $maxloadavg             =       ((x($_POST,'maxloadavg'))               ? intval(trim($_POST['maxloadavg']))            : 50);
388         $maxloadavg_frontend    =       ((x($_POST,'maxloadavg_frontend'))      ? intval(trim($_POST['maxloadavg_frontend']))   : 50);
389         $poco_completion        =       ((x($_POST,'poco_completion'))          ? intval(trim($_POST['poco_completion']))       : false);
390         $poco_requery_days      =       ((x($_POST,'poco_requery_days'))        ? intval(trim($_POST['poco_requery_days']))     : 7);
391         $poco_discovery         =       ((x($_POST,'poco_discovery'))           ? intval(trim($_POST['poco_discovery']))        : 0);
392         $poco_discovery_since   =       ((x($_POST,'poco_discovery_since'))     ? intval(trim($_POST['poco_discovery_since']))  : 30);
393         $poco_local_search      =       ((x($_POST,'poco_local_search'))        ? intval(trim($_POST['poco_local_search']))     : false);
394         $nodeinfo               =       ((x($_POST,'nodeinfo'))                 ? intval(trim($_POST['nodeinfo']))              : false);
395         $dfrn_only              =       ((x($_POST,'dfrn_only'))                ? True                                          : False);
396         $ostatus_disabled       =       !((x($_POST,'ostatus_disabled'))        ? True                                          : False);
397         $ostatus_poll_interval  =       ((x($_POST,'ostatus_poll_interval'))    ? intval(trim($_POST['ostatus_poll_interval'])) :  0);
398         $diaspora_enabled       =       ((x($_POST,'diaspora_enabled'))         ? True                                          : False);
399         $ssl_policy             =       ((x($_POST,'ssl_policy'))               ? intval($_POST['ssl_policy'])                  : 0);
400         $force_ssl              =       ((x($_POST,'force_ssl'))                ? True                                          : False);
401         $old_share              =       ((x($_POST,'old_share'))                ? True                                          : False);
402         $hide_help              =       ((x($_POST,'hide_help'))                ? True                                          : False);
403         $suppress_language      =       ((x($_POST,'suppress_language'))        ? True                                          : False);
404         $suppress_tags          =       ((x($_POST,'suppress_tags'))            ? True                                          : False);
405         $use_fulltext_engine    =       ((x($_POST,'use_fulltext_engine'))      ? True                                          : False);
406         $itemcache              =       ((x($_POST,'itemcache'))                ? notags(trim($_POST['itemcache']))             : '');
407         $itemcache_duration     =       ((x($_POST,'itemcache_duration'))       ? intval($_POST['itemcache_duration'])          : 0);
408         $max_comments           =       ((x($_POST,'max_comments'))             ? intval($_POST['max_comments'])                : 0);
409         $lockpath               =       ((x($_POST,'lockpath'))                 ? notags(trim($_POST['lockpath']))              : '');
410         $temppath               =       ((x($_POST,'temppath'))                 ? notags(trim($_POST['temppath']))              : '');
411         $basepath               =       ((x($_POST,'basepath'))                 ? notags(trim($_POST['basepath']))              : '');
412         $singleuser             =       ((x($_POST,'singleuser'))               ? notags(trim($_POST['singleuser']))            : '');
413         $proxy_disabled         =       ((x($_POST,'proxy_disabled'))           ? True                                          : False);
414         $old_pager              =       ((x($_POST,'old_pager'))                ? True                                          : False);
415         $only_tag_search        =       ((x($_POST,'only_tag_search'))          ? True                                          : False);
416         $rino                   =       ((x($_POST,'rino'))                             ? intval($_POST['rino'])                                : 0);
417         $embedly                =       ((x($_POST,'embedly'))                  ? notags(trim($_POST['embedly']))               : '');
418
419
420         if($ssl_policy != intval(get_config('system','ssl_policy'))) {
421                 if($ssl_policy == SSL_POLICY_FULL) {
422                         q("update `contact` set
423                                 `url`     = replace(`url`    , 'http:' , 'https:'),
424                                 `photo`   = replace(`photo`  , 'http:' , 'https:'),
425                                 `thumb`   = replace(`thumb`  , 'http:' , 'https:'),
426                                 `micro`   = replace(`micro`  , 'http:' , 'https:'),
427                                 `request` = replace(`request`, 'http:' , 'https:'),
428                                 `notify`  = replace(`notify` , 'http:' , 'https:'),
429                                 `poll`    = replace(`poll`   , 'http:' , 'https:'),
430                                 `confirm` = replace(`confirm`, 'http:' , 'https:'),
431                                 `poco`    = replace(`poco`   , 'http:' , 'https:')
432                                 where `self` = 1"
433                         );
434                         q("update `profile` set
435                                 `photo`   = replace(`photo`  , 'http:' , 'https:'),
436                                 `thumb`   = replace(`thumb`  , 'http:' , 'https:')
437                                 where 1 "
438                         );
439                 }
440                 elseif($ssl_policy == SSL_POLICY_SELFSIGN) {
441                         q("update `contact` set
442                                 `url`     = replace(`url`    , 'https:' , 'http:'),
443                                 `photo`   = replace(`photo`  , 'https:' , 'http:'),
444                                 `thumb`   = replace(`thumb`  , 'https:' , 'http:'),
445                                 `micro`   = replace(`micro`  , 'https:' , 'http:'),
446                                 `request` = replace(`request`, 'https:' , 'http:'),
447                                 `notify`  = replace(`notify` , 'https:' , 'http:'),
448                                 `poll`    = replace(`poll`   , 'https:' , 'http:'),
449                                 `confirm` = replace(`confirm`, 'https:' , 'http:'),
450                                 `poco`    = replace(`poco`   , 'https:' , 'http:')
451                                 where `self` = 1"
452                         );
453                         q("update `profile` set
454                                 `photo`   = replace(`photo`  , 'https:' , 'http:'),
455                                 `thumb`   = replace(`thumb`  , 'https:' , 'http:')
456                                 where 1 "
457                         );
458                 }
459         }
460         set_config('system','ssl_policy',$ssl_policy);
461         set_config('system','delivery_interval',$delivery_interval);
462         set_config('system','poll_interval',$poll_interval);
463         set_config('system','maxloadavg',$maxloadavg);
464         set_config('system','maxloadavg_frontend',$maxloadavg_frontend);
465         set_config('system','poco_completion',$poco_completion);
466         set_config('system','poco_requery_days',$poco_requery_days);
467         set_config('system','poco_discovery',$poco_discovery);
468         set_config('system','poco_discovery_since',$poco_discovery_since);
469         set_config('system','poco_local_search',$poco_local_search);
470         set_config('system','nodeinfo',$nodeinfo);
471         set_config('config','sitename',$sitename);
472         set_config('config','hostname',$hostname);
473         set_config('config','sender_email', $sender_email);
474         set_config('system','suppress_language',$suppress_language);
475         set_config('system','suppress_tags',$suppress_tags);
476         set_config('system','shortcut_icon',$shortcut_icon);
477         set_config('system','touch_icon',$touch_icon);
478
479         if ($banner==""){
480                 // don't know why, but del_config doesn't work...
481                 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
482                         dbesc("system"),
483                         dbesc("banner")
484                 );
485         } else {
486                 set_config('system','banner', $banner);
487         }
488         if ($info=="") {
489                 del_config('config','info');
490         } else {
491                 set_config('config','info',$info);
492         }
493         set_config('system','language', $language);
494         set_config('system','theme', $theme);
495         if ( $theme_mobile === '---' ) {
496                 del_config('system','mobile-theme');
497         } else {
498                 set_config('system','mobile-theme', $theme_mobile);
499                 }
500                 if ( $singleuser === '---' ) {
501                         del_config('system','singleuser');
502                 } else {
503                         set_config('system','singleuser', $singleuser);
504                 }
505         set_config('system','maximagesize', $maximagesize);
506         set_config('system','max_image_length', $maximagelength);
507         set_config('system','jpeg_quality', $jpegimagequality);
508
509         set_config('config','register_policy', $register_policy);
510         set_config('system','max_daily_registrations', $daily_registrations);
511         set_config('system','account_abandon_days', $abandon_days);
512         set_config('config','register_text', $register_text);
513         set_config('system','allowed_sites', $allowed_sites);
514         set_config('system','allowed_email', $allowed_email);
515         set_config('system','block_public', $block_public);
516         set_config('system','publish_all', $force_publish);
517         if ($global_directory==""){
518                 // don't know why, but del_config doesn't work...
519                 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
520                         dbesc("system"),
521                         dbesc("directory_submit_url")
522                 );
523         } else {
524                 set_config('system','directory_submit_url', $global_directory);
525         }
526         set_config('system','thread_allow', $thread_allow);
527         set_config('system','newuser_private', $newuser_private);
528         set_config('system','enotify_no_content', $enotify_no_content);
529         set_config('system','disable_embedded', $disable_embedded);
530         set_config('system','allow_users_remote_self', $allow_users_remote_self);
531
532         set_config('system','block_extended_register', $no_multi_reg);
533         set_config('system','no_openid', $no_openid);
534         set_config('system','no_regfullname', $no_regfullname);
535         set_config('system','community_page_style', $community_page_style);
536         set_config('system','max_author_posts_community_page', $max_author_posts_community_page);
537         set_config('system','no_utf', $no_utf);
538         set_config('system','verifyssl', $verifyssl);
539         set_config('system','proxyuser', $proxyuser);
540         set_config('system','proxy', $proxy);
541         set_config('system','curl_timeout', $timeout);
542         set_config('system','dfrn_only', $dfrn_only);
543         set_config('system','ostatus_disabled', $ostatus_disabled);
544         set_config('system','ostatus_poll_interval', $ostatus_poll_interval);
545         set_config('system','diaspora_enabled', $diaspora_enabled);
546         set_config('config','private_addons', $private_addons);
547
548         set_config('system','force_ssl', $force_ssl);
549         set_config('system','old_share', $old_share);
550         set_config('system','hide_help', $hide_help);
551         set_config('system','use_fulltext_engine', $use_fulltext_engine);
552         set_config('system','itemcache', $itemcache);
553         set_config('system','itemcache_duration', $itemcache_duration);
554         set_config('system','max_comments', $max_comments);
555         set_config('system','lockpath', $lockpath);
556         set_config('system','temppath', $temppath);
557         set_config('system','basepath', $basepath);
558         set_config('system','proxy_disabled', $proxy_disabled);
559         set_config('system','old_pager', $old_pager);
560         set_config('system','only_tag_search', $only_tag_search);
561
562         set_config('system','rino_encrypt', $rino);
563
564         set_config('system','embedly', $embedly);
565
566
567         info( t('Site settings updated.') . EOL);
568         goaway($a->get_baseurl(true) . '/admin/site' );
569         return; // NOTREACHED
570
571 }
572
573 /**
574  * @param  App $a
575  * @return string
576  */
577 function admin_page_site(&$a) {
578
579         /* Installed langs */
580         $lang_choices = array();
581         $langs = glob('view/*/strings.php');
582
583         if(is_array($langs) && count($langs)) {
584                 if(! in_array('view/en/strings.php',$langs))
585                         $langs[] = 'view/en/';
586                 asort($langs);
587                 foreach($langs as $l) {
588                         $t = explode("/",$l);
589                         $lang_choices[$t[1]] = $t[1];
590                 }
591         }
592
593         /* Installed themes */
594         $theme_choices = array();
595         $theme_choices_mobile = array();
596         $theme_choices_mobile["---"] = t("No special theme for mobile devices");
597         $files = glob('view/theme/*');
598         if($files) {
599                 foreach($files as $file) {
600                         $f = basename($file);
601                         $theme_name = ((file_exists($file . '/experimental')) ?  sprintf("%s - \x28Experimental\x29", $f) : $f);
602                         if (file_exists($file . '/mobile')) {
603                                 $theme_choices_mobile[$f] = $theme_name;
604                         }
605                 else {
606                                 $theme_choices[$f] = $theme_name;
607                         }
608                 }
609                 }
610
611                 /* Community page style */
612                 $community_page_style_choices = array(
613                         CP_NO_COMMUNITY_PAGE => t("No community page"),
614                         CP_USERS_ON_SERVER => t("Public postings from users of this site"),
615                         CP_GLOBAL_COMMUNITY => t("Global community page")
616                         );
617
618                 /* OStatus conversation poll choices */
619                 $ostatus_poll_choices = array(
620                         "-2" => t("Never"),
621                         "-1" => t("At post arrival"),
622                         "0" => t("Frequently"),
623                         "60" => t("Hourly"),
624                         "720" => t("Twice daily"),
625                         "1440" => t("Daily")
626                         );
627
628                 $poco_discovery_choices = array(
629                         "0" => t("Disabled"),
630                         "1" => t("Users"),
631                         "2" => t("Users, Global Contacts"),
632                         "3" => t("Users, Global Contacts/fallback"),
633                         );
634
635                 $poco_discovery_since_choices = array(
636                         "30" => t("One month"),
637                         "91" => t("Three months"),
638                         "182" => t("Half a year"),
639                         "365" => t("One year"),
640                         );
641
642                 /* get user names to make the install a personal install of X */
643                 $user_names = array();
644                 $user_names['---'] = t('Multi user instance');
645                 $users = q("SELECT username, nickname FROM `user`");
646                 foreach ($users as $user) {
647                         $user_names[$user['nickname']] = $user['username'];
648                 }
649
650         /* Banner */
651         $banner = get_config('system','banner');
652         if($banner == false)
653                 $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>';
654         $banner = htmlspecialchars($banner);
655         $info = get_config('config','info');
656         $info = htmlspecialchars($info);
657
658         // Automatically create temporary paths
659         get_temppath();
660         get_lockpath();
661         get_itemcachepath();
662
663         //echo "<pre>"; var_dump($lang_choices); die("</pre>");
664
665         /* Register policy */
666         $register_choices = Array(
667                 REGISTER_CLOSED => t("Closed"),
668                 REGISTER_APPROVE => t("Requires approval"),
669                 REGISTER_OPEN => t("Open")
670         );
671
672         $ssl_choices = array(
673                 SSL_POLICY_NONE => t("No SSL policy, links will track page SSL state"),
674                 SSL_POLICY_FULL => t("Force all links to use SSL"),
675                 SSL_POLICY_SELFSIGN => t("Self-signed certificate, use SSL for local links only (discouraged)")
676         );
677
678         if ($a->config['hostname'] == "")
679                 $a->config['hostname'] = $a->get_hostname();
680
681         $t = get_markup_template("admin_site.tpl");
682         return replace_macros($t, array(
683                 '$title' => t('Administration'),
684                 '$page' => t('Site'),
685                 '$submit' => t('Save Settings'),
686                 '$registration' => t('Registration'),
687                 '$upload' => t('File upload'),
688                 '$corporate' => t('Policies'),
689                 '$advanced' => t('Advanced'),
690                 '$portable_contacts' => t('Auto Discovered Contact Directory'),
691                 '$performance' => t('Performance'),
692                 '$relocate'=> t('Relocate - WARNING: advanced function. Could make this server unreachable.'),
693                 '$baseurl' => $a->get_baseurl(true),
694                 // name, label, value, help string, extra data...
695                 '$sitename'             => array('sitename', t("Site name"), $a->config['sitename'],''),
696                 '$hostname'             => array('hostname', t("Host name"), $a->config['hostname'], ""),
697                 '$sender_email'         => array('sender_email', t("Sender Email"), $a->config['sender_email'], t("The email address your server shall use to send notification emails from."), "", "", "email"),
698                 '$banner'               => array('banner', t("Banner/Logo"), $banner, ""),
699                 '$shortcut_icon'        => array('shortcut_icon', t("Shortcut icon"), get_config('system','shortcut_icon'),  t("Link to an icon that will be used for browsers.")),
700                 '$touch_icon'           => array('touch_icon', t("Touch icon"), get_config('system','touch_icon'),  t("Link to an icon that will be used for tablets and mobiles.")),
701                 '$info' => array('info',t('Additional Info'), $info, sprintf(t('For public servers: you can add additional information here that will be listed at %s/siteinfo.'), get_server())),
702                 '$language'             => array('language', t("System language"), get_config('system','language'), "", $lang_choices),
703                 '$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),
704                 '$theme_mobile'         => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile-theme'), t("Theme for mobile devices"), $theme_choices_mobile),
705                 '$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),
706                 '$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.")),
707                 '$old_share'            => array('old_share', t("Old style 'Share'"), get_config('system','old_share'), t("Deactivates the bbcode element 'share' for repeating items.")),
708                 '$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.")),
709                 '$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),
710                 '$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.")),
711                 '$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.")),
712                 '$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.")),
713
714                 '$register_policy'      => array('register_policy', t("Register policy"), $a->config['register_policy'], "", $register_choices),
715                 '$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.")),
716                 '$register_text'        => array('register_text', t("Register text"), $a->config['register_text'], t("Will be displayed prominently on the registration page.")),
717                 '$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.')),
718                 '$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")),
719                 '$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")),
720                 '$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.")),
721                 '$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.")),
722                 '$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.")),
723                 '$thread_allow'         => array('thread_allow', t("Allow threaded items"), get_config('system','thread_allow'), t("Allow infinite level threading for items on this site.")),
724                 '$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.")),
725                 '$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.")),
726                 '$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.")),
727                 '$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.")),
728                 '$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.')),
729                 '$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.")),
730                 '$no_openid'            => array('no_openid', t("OpenID support"), !get_config('system','no_openid'), t("OpenID support for registration and logins.")),
731                 '$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")),
732                 '$no_utf'               => array('no_utf', t("UTF-8 Regular expressions"), !get_config('system','no_utf'), t("Use PHP UTF8 regular expressions")),
733                 '$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),
734                 '$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')")),
735                 '$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.")),
736                 '$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),
737                 '$diaspora_enabled'     => array('diaspora_enabled', t("Enable Diaspora support"), get_config('system','diaspora_enabled'), t("Provide built-in Diaspora network compatibility.")),
738                 '$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.")),
739                 '$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.")),
740                 '$proxyuser'            => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""),
741                 '$proxy'                => array('proxy', t("Proxy URL"), get_config('system','proxy'), ""),
742                 '$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).")),
743                 '$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.")),
744                 '$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.")),
745                 '$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.")),
746                 '$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.")),
747
748                 '$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.")),
749                 '$poco_requery_days'    => array('poco_requery_days', t("Days between requery"), get_config('system','poco_requery_days'), t("Number of days after which a server is requeried for his contacts.")),
750                 '$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),
751                 '$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),
752                 '$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.")),
753
754                 '$nodeinfo'             => array('nodeinfo', t("Publish server information"), get_config('system','nodeinfo'), t("If enabled, general server and usage data will be published. The data contains the name and version of the server, number of users with public profiles, number of posts and the activated protocols and connectors. See <a href='http://the-federation.info/'>the-federation.info</a> for details.")),
755
756                 '$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.")),
757                 '$suppress_language'    => array('suppress_language', t("Suppress Language"), get_config('system','suppress_language'), t("Suppress language information in meta information about a posting.")),
758                 '$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.")),
759                 '$itemcache'            => array('itemcache', t("Path to item cache"), get_config('system','itemcache'), t("The item caches buffers generated bbcode and external images.")),
760                 '$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.")),
761                 '$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.")),
762                 '$lockpath'             => array('lockpath', t("Path for lock file"), get_config('system','lockpath'), t("The lock file is used to avoid multiple pollers at one time. Only define a folder here.")),
763                 '$temppath'             => array('temppath', t("Temp path"), get_config('system','temppath'), t("If you have a restricted system where the webserver can't access the system temp path, enter another path here.")),
764                 '$basepath'             => array('basepath', t("Base path to installation"), get_config('system','basepath'), t("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.")),
765                 '$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.")),
766                 '$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.")),
767                 '$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.")),
768
769                 '$relocate_url'         => array('relocate_url', t("New base url"), $a->get_baseurl(), t("Change base url for this server. Sends relocate message to all DFRN contacts of all users.")),
770
771                 '$rino'                 => array('rino', t("RINO Encryption"), intval(get_config('system','rino_encrypt')), t("Encryption layer between nodes."), array("Disabled", "RINO1 (deprecated)", "RINO2")),
772                 '$embedly'              => array('embedly', t("Embedly API key"), get_config('system','embedly'), t("<a href='http://embed.ly'>Embedly</a> is used to fetch additional data for web pages. This is an optional parameter.")),
773
774                 '$form_security_token' => get_form_security_token("admin_site")
775
776         ));
777
778 }
779
780
781 function admin_page_dbsync(&$a) {
782
783         $o = '';
784
785         if($a->argc > 3 && intval($a->argv[3]) && $a->argv[2] === 'mark') {
786                 set_config('database', 'update_' . intval($a->argv[3]), 'success');
787                 $curr = get_config('system','build');
788                 if(intval($curr) == intval($a->argv[3]))
789                         set_config('system','build',intval($curr) + 1);
790                 info( t('Update has been marked successful') . EOL);
791                 goaway($a->get_baseurl(true) . '/admin/dbsync');
792         }
793
794         if(($a->argc > 2) AND (intval($a->argv[2]) OR ($a->argv[2] === 'check'))) {
795                 require_once("include/dbstructure.php");
796                 $retval = update_structure(false, true);
797                 if (!$retval) {
798                         $o .= sprintf(t("Database structure update %s was successfully applied."), DB_UPDATE_VERSION)."<br />";
799                         set_config('database', 'dbupdate_'.DB_UPDATE_VERSION, 'success');
800                 } else
801                         $o .= sprintf(t("Executing of database structure update %s failed with error: %s"),
802                                         DB_UPDATE_VERSION, $retval)."<br />";
803                 if ($a->argv[2] === 'check')
804                         return $o;
805         }
806
807         if ($a->argc > 2 && intval($a->argv[2])) {
808                 require_once('update.php');
809                 $func = 'update_' . intval($a->argv[2]);
810                 if(function_exists($func)) {
811                         $retval = $func();
812                         if($retval === UPDATE_FAILED) {
813                                 $o .= sprintf(t("Executing %s failed with error: %s"), $func, $retval);
814                         }
815                         elseif($retval === UPDATE_SUCCESS) {
816                                 $o .= sprintf(t('Update %s was successfully applied.', $func));
817                                 set_config('database',$func, 'success');
818                         }
819                         else
820                                 $o .= sprintf(t('Update %s did not return a status. Unknown if it succeeded.'), $func);
821                 } else {
822                         $o .= sprintf(t('There was no additional update function %s that needed to be called.'), $func)."<br />";
823                         set_config('database',$func, 'success');
824                 }
825                 return $o;
826         }
827
828         $failed = array();
829         $r = q("select k, v from config where `cat` = 'database' ");
830         if(count($r)) {
831                 foreach($r as $rr) {
832                         $upd = intval(substr($rr['k'],7));
833                         if($upd < 1139 || $rr['v'] === 'success')
834                                 continue;
835                         $failed[] = $upd;
836                 }
837         }
838         if(! count($failed)) {
839                 $o = replace_macros(get_markup_template('structure_check.tpl'),array(
840                         '$base' => $a->get_baseurl(true),
841                         '$banner' => t('No failed updates.'),
842                         '$check' => t('Check database structure'),
843                 ));
844         } else {
845                 $o = replace_macros(get_markup_template('failed_updates.tpl'),array(
846                         '$base' => $a->get_baseurl(true),
847                         '$banner' => t('Failed Updates'),
848                         '$desc' => t('This does not include updates prior to 1139, which did not return a status.'),
849                         '$mark' => t('Mark success (if update was manually applied)'),
850                         '$apply' => t('Attempt to execute this update step automatically'),
851                         '$failed' => $failed
852                 ));
853         }
854
855         return $o;
856
857 }
858
859 /**
860  * Users admin page
861  *
862  * @param App $a
863  */
864 function admin_page_users_post(&$a){
865         $pending = ( x($_POST, 'pending') ? $_POST['pending'] : Array() );
866         $users = ( x($_POST, 'user') ? $_POST['user'] : Array() );
867         $nu_name = ( x($_POST, 'new_user_name') ? $_POST['new_user_name'] : '');
868         $nu_nickname = ( x($_POST, 'new_user_nickname') ? $_POST['new_user_nickname'] : '');
869         $nu_email = ( x($_POST, 'new_user_email') ? $_POST['new_user_email'] : '');
870
871         check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
872
873         if (!($nu_name==="") && !($nu_email==="") && !($nu_nickname==="")) {
874                 require_once('include/user.php');
875
876                 $result = create_user( array('username'=>$nu_name, 'email'=>$nu_email, 'nickname'=>$nu_nickname, 'verified'=>1)  );
877                 if(! $result['success']) {
878                         notice($result['message']);
879                         return;
880                 }
881                 $nu = $result['user'];
882                 $preamble = deindent(t('
883                         Dear %1$s,
884                                 the administrator of %2$s has set up an account for you.'));
885                 $body = deindent(t('
886                         The login details are as follows:
887
888                         Site Location:  %1$s
889                         Login Name:             %2$s
890                         Password:               %3$s
891
892                         You may change your password from your account "Settings" page after logging
893                         in.
894
895                         Please take a few moments to review the other account settings on that page.
896
897                         You may also wish to add some basic information to your default profile
898                         (on the "Profiles" page) so that other people can easily find you.
899
900                         We recommend setting your full name, adding a profile photo,
901                         adding some profile "keywords" (very useful in making new friends) - and
902                         perhaps what country you live in; if you do not wish to be more specific
903                         than that.
904
905                         We fully respect your right to privacy, and none of these items are necessary.
906                         If you are new and do not know anybody here, they may help
907                         you to make some new and interesting friends.
908
909                         Thank you and welcome to %4$s.'));
910
911                 $preamble = sprintf($preamble, $nu['username'], $a->config['sitename']);
912                 $body = sprintf($body, $a->get_baseurl(), $nu['email'], $result['password'], $a->config['sitename']);
913
914                 notification(array(
915                         'type' => "SYSTEM_EMAIL",
916                         'to_email' => $nu['email'],
917                         'subject'=> sprintf( t('Registration details for %s'), $a->config['sitename']),
918                         'preamble'=> $preamble,
919                         'body' => $body));
920
921         }
922
923         if (x($_POST,'page_users_block')){
924                 foreach($users as $uid){
925                         q("UPDATE `user` SET `blocked`=1-`blocked` WHERE `uid`=%s",
926                                 intval( $uid )
927                         );
928                 }
929                 notice( sprintf( tt("%s user blocked/unblocked", "%s users blocked/unblocked", count($users)), count($users)) );
930         }
931         if (x($_POST,'page_users_delete')){
932                 require_once("include/Contact.php");
933                 foreach($users as $uid){
934                         user_remove($uid);
935                 }
936                 notice( sprintf( tt("%s user deleted", "%s users deleted", count($users)), count($users)) );
937         }
938
939         if (x($_POST,'page_users_approve')){
940                 require_once("mod/regmod.php");
941                 foreach($pending as $hash){
942                         user_allow($hash);
943                 }
944         }
945         if (x($_POST,'page_users_deny')){
946                 require_once("mod/regmod.php");
947                 foreach($pending as $hash){
948                         user_deny($hash);
949                 }
950         }
951         goaway($a->get_baseurl(true) . '/admin/users' );
952         return; // NOTREACHED
953 }
954
955 /**
956  * @param App $a
957  * @return string
958  */
959 function admin_page_users(&$a){
960         if ($a->argc>2) {
961                 $uid = $a->argv[3];
962                 $user = q("SELECT username, blocked FROM `user` WHERE `uid`=%d", intval($uid));
963                 if (count($user)==0){
964                         notice( 'User not found' . EOL);
965                         goaway($a->get_baseurl(true) . '/admin/users' );
966                         return ''; // NOTREACHED
967                 }
968                 switch($a->argv[2]){
969                         case "delete":{
970                                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
971                                 // delete user
972                                 require_once("include/Contact.php");
973                                 user_remove($uid);
974
975                                 notice( sprintf(t("User '%s' deleted"), $user[0]['username']) . EOL);
976                         }; break;
977                         case "block":{
978                                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
979                                 q("UPDATE `user` SET `blocked`=%d WHERE `uid`=%s",
980                                         intval( 1-$user[0]['blocked'] ),
981                                         intval( $uid )
982                                 );
983                                 notice( sprintf( ($user[0]['blocked']?t("User '%s' unblocked"):t("User '%s' blocked")) , $user[0]['username']) . EOL);
984                         }; break;
985                 }
986                 goaway($a->get_baseurl(true) . '/admin/users' );
987                 return ''; // NOTREACHED
988
989         }
990
991         /* get pending */
992         $pending = q("SELECT `register`.*, `contact`.`name`, `user`.`email`
993                                  FROM `register`
994                                  LEFT JOIN `contact` ON `register`.`uid` = `contact`.`uid`
995                                  LEFT JOIN `user` ON `register`.`uid` = `user`.`uid`;");
996
997
998         /* get users */
999
1000         $total = q("SELECT count(*) as total FROM `user` where 1");
1001         if(count($total)) {
1002                 $a->set_pager_total($total[0]['total']);
1003                 $a->set_pager_itemspage(100);
1004         }
1005
1006
1007         $users = q("SELECT `user` . * , `contact`.`name` , `contact`.`url` , `contact`.`micro`, `lastitem`.`lastitem_date`, `user`.`account_expired`
1008                                 FROM
1009                                         (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid`
1010                                         FROM `item`
1011                                         WHERE `item`.`type` = 'wall'
1012                                         GROUP BY `item`.`uid`) AS `lastitem`
1013                                                  RIGHT OUTER JOIN `user` ON `user`.`uid` = `lastitem`.`uid`,
1014                                            `contact`
1015                                 WHERE
1016                                            `user`.`uid` = `contact`.`uid`
1017                                                 AND `user`.`verified` =1
1018                                         AND `contact`.`self` =1
1019                                 ORDER BY `contact`.`name` LIMIT %d, %d
1020                                 ",
1021                                 intval($a->pager['start']),
1022                                 intval($a->pager['itemspage'])
1023                                 );
1024
1025         $adminlist = explode(",", str_replace(" ", "", $a->config['admin_email']));
1026         $_setup_users = function ($e) use ($adminlist){
1027                 $accounts = Array(
1028                         t('Normal Account'),
1029                         t('Soapbox Account'),
1030                         t('Community/Celebrity Account'),
1031                                                 t('Automatic Friend Account')
1032                 );
1033                 $e['page-flags'] = $accounts[$e['page-flags']];
1034                 $e['register_date'] = relative_date($e['register_date']);
1035                 $e['login_date'] = relative_date($e['login_date']);
1036                 $e['lastitem_date'] = relative_date($e['lastitem_date']);
1037                 //$e['is_admin'] = ($e['email'] === $a->config['admin_email']);
1038                 $e['is_admin'] = in_array($e['email'], $adminlist);
1039                 $e['is_deletable'] = (intval($e['uid']) != local_user());
1040                 $e['deleted'] = ($e['account_removed']?relative_date($e['account_expires_on']):False);
1041                 return $e;
1042         };
1043         $users = array_map($_setup_users, $users);
1044
1045
1046         // Get rid of dashes in key names, Smarty3 can't handle them
1047         // and extracting deleted users
1048
1049         $tmp_users = Array();
1050         $deleted = Array();
1051
1052         while(count($users)) {
1053                 $new_user = Array();
1054                 foreach( array_pop($users) as $k => $v) {
1055                         $k = str_replace('-','_',$k);
1056                         $new_user[$k] = $v;
1057                 }
1058                 if($new_user['deleted']) {
1059                         array_push($deleted, $new_user);
1060                 }
1061                 else {
1062                         array_push($tmp_users, $new_user);
1063                 }
1064         }
1065         //Reversing the two array, and moving $tmp_users to $users
1066         array_reverse($deleted);
1067         while(count($tmp_users)) {
1068                 array_push($users, array_pop($tmp_users));
1069         }
1070
1071         $t = get_markup_template("admin_users.tpl");
1072         $o = replace_macros($t, array(
1073                 // strings //
1074                 '$title' => t('Administration'),
1075                 '$page' => t('Users'),
1076                 '$submit' => t('Add User'),
1077                 '$select_all' => t('select all'),
1078                 '$h_pending' => t('User registrations waiting for confirm'),
1079                 '$h_deleted' => t('User waiting for permanent deletion'),
1080                 '$th_pending' => array( t('Request date'), t('Name'), t('Email') ),
1081                 '$no_pending' =>  t('No registrations.'),
1082                 '$approve' => t('Approve'),
1083                 '$deny' => t('Deny'),
1084                 '$delete' => t('Delete'),
1085                 '$block' => t('Block'),
1086                 '$unblock' => t('Unblock'),
1087                 '$siteadmin' => t('Site admin'),
1088                 '$accountexpired' => t('Account expired'),
1089
1090                 '$h_users' => t('Users'),
1091                 '$h_newuser' => t('New User'),
1092                 '$th_deleted' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'), t('Deleted since') ),
1093                 '$th_users' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'),  t('Account') ),
1094
1095                 '$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?'),
1096                 '$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?'),
1097
1098                 '$form_security_token' => get_form_security_token("admin_users"),
1099
1100                 // values //
1101                 '$baseurl' => $a->get_baseurl(true),
1102
1103                 '$pending' => $pending,
1104                 'deleted' => $deleted,
1105                 '$users' => $users,
1106                 '$newusername'  => array('new_user_name', t("Name"), '', t("Name of the new user.")),
1107                 '$newusernickname'  => array('new_user_nickname', t("Nickname"), '', t("Nickname of the new user.")),
1108                 '$newuseremail'  => array('new_user_email', t("Email"), '', t("Email address of the new user."), '', '', 'email'),
1109         ));
1110         $o .= paginate($a);
1111         return $o;
1112 }
1113
1114
1115 /**
1116  * Plugins admin page
1117  *
1118  * @param App $a
1119  * @return string
1120  */
1121 function admin_page_plugins(&$a){
1122
1123         /**
1124          * Single plugin
1125          */
1126         if ($a->argc == 3){
1127                 $plugin = $a->argv[2];
1128                 if (!is_file("addon/$plugin/$plugin.php")){
1129                         notice( t("Item not found.") );
1130                         return '';
1131                 }
1132
1133                 if (x($_GET,"a") && $_GET['a']=="t"){
1134                         check_form_security_token_redirectOnErr('/admin/plugins', 'admin_themes', 't');
1135
1136                         // Toggle plugin status
1137                         $idx = array_search($plugin, $a->plugins);
1138                         if ($idx !== false){
1139                                 unset($a->plugins[$idx]);
1140                                 uninstall_plugin($plugin);
1141                                 info( sprintf( t("Plugin %s disabled."), $plugin ) );
1142                         } else {
1143                                 $a->plugins[] = $plugin;
1144                                 install_plugin($plugin);
1145                                 info( sprintf( t("Plugin %s enabled."), $plugin ) );
1146                         }
1147                         set_config("system","addon", implode(", ",$a->plugins));
1148                         goaway($a->get_baseurl(true) . '/admin/plugins' );
1149                         return ''; // NOTREACHED
1150                 }
1151                 // display plugin details
1152                 require_once('library/markdown.php');
1153
1154                 if (in_array($plugin, $a->plugins)){
1155                         $status="on"; $action= t("Disable");
1156                 } else {
1157                         $status="off"; $action= t("Enable");
1158                 }
1159
1160                 $readme=Null;
1161                 if (is_file("addon/$plugin/README.md")){
1162                         $readme = file_get_contents("addon/$plugin/README.md");
1163                         $readme = Markdown($readme);
1164                 } else if (is_file("addon/$plugin/README")){
1165                         $readme = "<pre>". file_get_contents("addon/$plugin/README") ."</pre>";
1166                 }
1167
1168                 $admin_form="";
1169                 if (is_array($a->plugins_admin) && in_array($plugin, $a->plugins_admin)){
1170                         @require_once("addon/$plugin/$plugin.php");
1171                         $func = $plugin.'_plugin_admin';
1172                         $func($a, $admin_form);
1173                 }
1174
1175                 $t = get_markup_template("admin_plugins_details.tpl");
1176
1177                 return replace_macros($t, array(
1178                         '$title' => t('Administration'),
1179                         '$page' => t('Plugins'),
1180                         '$toggle' => t('Toggle'),
1181                         '$settings' => t('Settings'),
1182                         '$baseurl' => $a->get_baseurl(true),
1183
1184                         '$plugin' => $plugin,
1185                         '$status' => $status,
1186                         '$action' => $action,
1187                         '$info' => get_plugin_info($plugin),
1188                         '$str_author' => t('Author: '),
1189                         '$str_maintainer' => t('Maintainer: '),
1190
1191                         '$admin_form' => $admin_form,
1192                         '$function' => 'plugins',
1193                         '$screenshot' => '',
1194                         '$readme' => $readme,
1195
1196                         '$form_security_token' => get_form_security_token("admin_themes"),
1197                 ));
1198         }
1199
1200
1201
1202         /**
1203          * List plugins
1204          */
1205
1206     if (x($_GET,"a") && $_GET['a']=="r"){
1207                 check_form_security_token_redirectOnErr($a->get_baseurl().'/admin/plugins', 'admin_themes', 't');
1208                 reload_plugins();
1209                 info("Plugins reloaded");
1210                 goaway($a->get_baseurl().'/admin/plugins');
1211         }
1212
1213         $plugins = array();
1214         $files = glob("addon/*/"); /* */
1215         if($files) {
1216                 foreach($files as $file) {
1217                         if (is_dir($file)){
1218                                 list($tmp, $id)=array_map("trim", explode("/",$file));
1219                                 $info = get_plugin_info($id);
1220                                 $show_plugin = true;
1221
1222                                 // If the addon is unsupported, then only show it, when it is enabled
1223                                 if ((strtolower($info["status"]) == "unsupported") AND !in_array($id,  $a->plugins))
1224                                         $show_plugin = false;
1225
1226                                 // Override the above szenario, when the admin really wants to see outdated stuff
1227                                 if (get_config("system", "show_unsupported_addons"))
1228                                         $show_plugin = true;
1229
1230                                 if ($show_plugin)
1231                                         $plugins[] = array($id, (in_array($id,  $a->plugins)?"on":"off") , $info);
1232                         }
1233                 }
1234         }
1235
1236         $t = get_markup_template("admin_plugins.tpl");
1237         return replace_macros($t, array(
1238                 '$title' => t('Administration'),
1239                 '$page' => t('Plugins'),
1240                 '$submit' => t('Save Settings'),
1241                 '$baseurl' => $a->get_baseurl(true),
1242                 '$function' => 'plugins',
1243                 '$plugins' => $plugins,
1244                 '$form_security_token' => get_form_security_token("admin_themes"),
1245         ));
1246 }
1247
1248 /**
1249  * @param array $themes
1250  * @param string $th
1251  * @param int $result
1252  */
1253 function toggle_theme(&$themes,$th,&$result) {
1254         for($x = 0; $x < count($themes); $x ++) {
1255                 if($themes[$x]['name'] === $th) {
1256                         if($themes[$x]['allowed']) {
1257                                 $themes[$x]['allowed'] = 0;
1258                                 $result = 0;
1259                         }
1260                         else {
1261                                 $themes[$x]['allowed'] = 1;
1262                                 $result = 1;
1263                         }
1264                 }
1265         }
1266 }
1267
1268 /**
1269  * @param array $themes
1270  * @param string $th
1271  * @return int
1272  */
1273 function theme_status($themes,$th) {
1274         for($x = 0; $x < count($themes); $x ++) {
1275                 if($themes[$x]['name'] === $th) {
1276                         if($themes[$x]['allowed']) {
1277                                 return 1;
1278                         }
1279                         else {
1280                                 return 0;
1281                         }
1282                 }
1283         }
1284         return 0;
1285 }
1286
1287
1288 /**
1289  * @param array $themes
1290  * @return string
1291  */
1292 function rebuild_theme_table($themes) {
1293         $o = '';
1294         if(count($themes)) {
1295                 foreach($themes as $th) {
1296                         if($th['allowed']) {
1297                                 if(strlen($o))
1298                                         $o .= ',';
1299                                 $o .= $th['name'];
1300                         }
1301                 }
1302         }
1303         return $o;
1304 }
1305
1306
1307 /**
1308  * Themes admin page
1309  *
1310  * @param App $a
1311  * @return string
1312  */
1313 function admin_page_themes(&$a){
1314
1315         $allowed_themes_str = get_config('system','allowed_themes');
1316         $allowed_themes_raw = explode(',',$allowed_themes_str);
1317         $allowed_themes = array();
1318         if(count($allowed_themes_raw))
1319                 foreach($allowed_themes_raw as $x)
1320                         if(strlen(trim($x)))
1321                                 $allowed_themes[] = trim($x);
1322
1323         $themes = array();
1324         $files = glob('view/theme/*'); /* */
1325         if($files) {
1326                 foreach($files as $file) {
1327                         $f = basename($file);
1328                         $is_experimental = intval(file_exists($file . '/experimental'));
1329                         $is_supported = 1-(intval(file_exists($file . '/unsupported')));
1330                         $is_allowed = intval(in_array($f,$allowed_themes));
1331
1332                         if ($is_allowed OR $is_supported OR get_config("system", "show_unsupported_themes"))
1333                                 $themes[] = array('name' => $f, 'experimental' => $is_experimental, 'supported' => $is_supported, 'allowed' => $is_allowed);
1334                 }
1335         }
1336
1337         if(! count($themes)) {
1338                 notice( t('No themes found.'));
1339                 return '';
1340         }
1341
1342         /**
1343          * Single theme
1344          */
1345
1346         if ($a->argc == 3){
1347                 $theme = $a->argv[2];
1348                 if(! is_dir("view/theme/$theme")){
1349                         notice( t("Item not found.") );
1350                         return '';
1351                 }
1352
1353                 if (x($_GET,"a") && $_GET['a']=="t"){
1354                         check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't');
1355
1356                         // Toggle theme status
1357
1358                         toggle_theme($themes,$theme,$result);
1359                         $s = rebuild_theme_table($themes);
1360                         if($result) {
1361                                 install_theme($theme);
1362                                 info( sprintf('Theme %s enabled.',$theme));
1363                         }
1364                         else {
1365                                 uninstall_theme($theme);
1366                                 info( sprintf('Theme %s disabled.',$theme));
1367                         }
1368
1369                         set_config('system','allowed_themes',$s);
1370                         goaway($a->get_baseurl(true) . '/admin/themes' );
1371                         return ''; // NOTREACHED
1372                 }
1373
1374                 // display theme details
1375                 require_once('library/markdown.php');
1376
1377                 if (theme_status($themes,$theme)) {
1378                         $status="on"; $action= t("Disable");
1379                 } else {
1380                         $status="off"; $action= t("Enable");
1381                 }
1382
1383                 $readme=Null;
1384                 if (is_file("view/theme/$theme/README.md")){
1385                         $readme = file_get_contents("view/theme/$theme/README.md");
1386                         $readme = Markdown($readme);
1387                 } else if (is_file("view/theme/$theme/README")){
1388                         $readme = "<pre>". file_get_contents("view/theme/$theme/README") ."</pre>";
1389                 }
1390
1391                 $admin_form="";
1392                 if (is_file("view/theme/$theme/config.php")){
1393                         require_once("view/theme/$theme/config.php");
1394                         if(function_exists("theme_admin")){
1395                                 $admin_form = theme_admin($a);
1396                         }
1397
1398                 }
1399
1400                 $screenshot = array( get_theme_screenshot($theme), t('Screenshot'));
1401                 if(! stristr($screenshot[0],$theme))
1402                         $screenshot = null;
1403
1404                 $t = get_markup_template("admin_plugins_details.tpl");
1405                 return replace_macros($t, array(
1406                         '$title' => t('Administration'),
1407                         '$page' => t('Themes'),
1408                         '$toggle' => t('Toggle'),
1409                         '$settings' => t('Settings'),
1410                         '$baseurl' => $a->get_baseurl(true),
1411
1412                         '$plugin' => $theme,
1413                         '$status' => $status,
1414                         '$action' => $action,
1415                         '$info' => get_theme_info($theme),
1416                         '$function' => 'themes',
1417                         '$admin_form' => $admin_form,
1418                         '$str_author' => t('Author: '),
1419                         '$str_maintainer' => t('Maintainer: '),
1420                         '$screenshot' => $screenshot,
1421                         '$readme' => $readme,
1422
1423                         '$form_security_token' => get_form_security_token("admin_themes"),
1424                 ));
1425         }
1426
1427         /**
1428          * List themes
1429          */
1430
1431         $xthemes = array();
1432         if($themes) {
1433                 foreach($themes as $th) {
1434                         $xthemes[] = array($th['name'],(($th['allowed']) ? "on" : "off"), get_theme_info($th['name']));
1435                 }
1436         }
1437
1438         $t = get_markup_template("admin_plugins.tpl");
1439         return replace_macros($t, array(
1440                 '$title' => t('Administration'),
1441                 '$page' => t('Themes'),
1442                 '$submit' => t('Save Settings'),
1443                 '$baseurl' => $a->get_baseurl(true),
1444                 '$function' => 'themes',
1445                 '$plugins' => $xthemes,
1446                 '$experimental' => t('[Experimental]'),
1447                 '$unsupported' => t('[Unsupported]'),
1448                 '$form_security_token' => get_form_security_token("admin_themes"),
1449         ));
1450 }
1451
1452
1453 /**
1454  * Logs admin page
1455  *
1456  * @param App $a
1457  */
1458
1459 function admin_page_logs_post(&$a) {
1460         if (x($_POST,"page_logs")) {
1461                 check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
1462
1463                 $logfile                =       ((x($_POST,'logfile'))          ? notags(trim($_POST['logfile']))       : '');
1464                 $debugging              =       ((x($_POST,'debugging'))        ? true                                                          : false);
1465                 $loglevel               =       ((x($_POST,'loglevel'))         ? intval(trim($_POST['loglevel']))      : 0);
1466
1467                 set_config('system','logfile', $logfile);
1468                 set_config('system','debugging',  $debugging);
1469                 set_config('system','loglevel', $loglevel);
1470
1471
1472         }
1473
1474         info( t("Log settings updated.") );
1475         goaway($a->get_baseurl(true) . '/admin/logs' );
1476         return; // NOTREACHED
1477 }
1478
1479 /**
1480  * @param App $a
1481  * @return string
1482  */
1483 function admin_page_logs(&$a){
1484
1485         $log_choices = Array(
1486                 LOGGER_NORMAL => 'Normal',
1487                 LOGGER_TRACE => 'Trace',
1488                 LOGGER_DEBUG => 'Debug',
1489                 LOGGER_DATA => 'Data',
1490                 LOGGER_ALL => 'All'
1491         );
1492
1493         $t = get_markup_template("admin_logs.tpl");
1494
1495         $f = get_config('system','logfile');
1496
1497         $data = '';
1498
1499         if(!file_exists($f)) {
1500                 $data = t("Error trying to open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f exist and is
1501 readable.");
1502         }
1503         else {
1504                 $fp = fopen($f, 'r');
1505                 if(!$fp) {
1506                         $data = t("Couldn't open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f is readable.");
1507                 }
1508                 else {
1509                         $fstat = fstat($fp);
1510                         $size = $fstat['size'];
1511                         if($size != 0)
1512                         {
1513                                 if($size > 5000000 || $size < 0)
1514                                         $size = 5000000;
1515                                 $seek = fseek($fp,0-$size,SEEK_END);
1516                                 if($seek === 0) {
1517                                         $data = escape_tags(fread($fp,$size));
1518                                         while(! feof($fp))
1519                                                 $data .= escape_tags(fread($fp,4096));
1520                                 }
1521                         }
1522                         fclose($fp);
1523                 }
1524         }
1525
1526         return replace_macros($t, array(
1527                 '$title' => t('Administration'),
1528                 '$page' => t('Logs'),
1529                 '$submit' => t('Save Settings'),
1530                 '$clear' => t('Clear'),
1531                 '$data' => $data,
1532                 '$baseurl' => $a->get_baseurl(true),
1533                 '$logname' =>  get_config('system','logfile'),
1534
1535                                                                         // name, label, value, help string, extra data...
1536                 '$debugging'            => array('debugging', t("Enable Debugging"),get_config('system','debugging'), ""),
1537                 '$logfile'                      => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Friendica top-level directory.")),
1538                 '$loglevel'             => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices),
1539
1540                 '$form_security_token' => get_form_security_token("admin_logs"),
1541         ));
1542 }
1543
1544 /**
1545  * @param App $a
1546  */
1547 function admin_page_remoteupdate_post(&$a) {
1548         // this function should be called via ajax post
1549         if(!is_site_admin()) {
1550                 return;
1551         }
1552
1553
1554         if (x($_POST,'remotefile') && $_POST['remotefile']!=""){
1555                 $remotefile = $_POST['remotefile'];
1556                 $ftpdata = (x($_POST['ftphost'])?$_POST:false);
1557                 doUpdate($remotefile, $ftpdata);
1558         } else {
1559                 echo "No remote file to download. Abort!";
1560         }
1561
1562         killme();
1563 }
1564
1565 /**
1566  * @param App $a
1567  * @return string
1568  */
1569 function admin_page_remoteupdate(&$a) {
1570         if(!is_site_admin()) {
1571                 return login(false);
1572         }
1573
1574         $canwrite = canWeWrite();
1575         $canftp = function_exists('ftp_connect');
1576
1577         $needupdate = true;
1578         $u = checkUpdate();
1579         if (!is_array($u)){
1580                 $needupdate = false;
1581                 $u = array('','','');
1582         }
1583
1584         $tpl = get_markup_template("admin_remoteupdate.tpl");
1585         return replace_macros($tpl, array(
1586                 '$baseurl' => $a->get_baseurl(true),
1587                 '$submit' => t("Update now"),
1588                 '$close' => t("Close"),
1589                 '$localversion' => FRIENDICA_VERSION,
1590                 '$remoteversion' => $u[1],
1591                 '$needupdate' => $needupdate,
1592                 '$canwrite' => $canwrite,
1593                 '$canftp'       => $canftp,
1594                 '$ftphost'      => array('ftphost', t("FTP Host"), '',''),
1595                 '$ftppath'      => array('ftppath', t("FTP Path"), '/',''),
1596                 '$ftpuser'      => array('ftpuser', t("FTP User"), '',''),
1597                 '$ftppwd'       => array('ftppwd', t("FTP Password"), '',''),
1598                 '$remotefile'=>array('remotefile','', $u['2'],''),
1599         ));
1600
1601 }