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