]> git.mxchange.org Git - friendica.git/blob - mod/admin.php
Merge pull request #654 from mexon/filter_var
[friendica.git] / mod / admin.php
1 <?php
2
3  /**
4   * Friendica admin
5   */
6 require_once("include/remoteupdate.php");
7
8
9 /**
10  * @param App $a
11  */
12 function admin_post(&$a){
13
14
15         if(!is_site_admin()) {
16                 return;
17         }
18
19         // do not allow a page manager to access the admin panel at all.
20
21         if(x($_SESSION,'submanage') && intval($_SESSION['submanage']))
22                 return;
23
24
25
26         // urls
27         if ($a->argc > 1){
28                 switch ($a->argv[1]){
29                         case 'site':
30                                 admin_page_site_post($a);
31                                 break;
32                         case 'users':
33                                 admin_page_users_post($a);
34                                 break;
35                         case 'plugins':
36                                 if ($a->argc > 2 && 
37                                         is_file("addon/".$a->argv[2]."/".$a->argv[2].".php")){
38                                                 @include_once("addon/".$a->argv[2]."/".$a->argv[2].".php");
39                                                 if(function_exists($a->argv[2].'_plugin_admin_post')) {
40                                                         $func = $a->argv[2].'_plugin_admin_post';
41                                                         $func($a);
42                                                 }
43                                 }
44                                 goaway($a->get_baseurl(true) . '/admin/plugins/' . $a->argv[2] );
45                                 return; // NOTREACHED
46                                 break;
47                         case 'themes':
48                                 $theme = $a->argv[2];
49                                 if (is_file("view/theme/$theme/config.php")){
50                                         require_once("view/theme/$theme/config.php");
51                                         if (function_exists("theme_admin_post")){
52                                                 theme_admin_post($a);
53                                         }
54                                 }
55                                 info(t('Theme settings updated.'));
56                                 if(is_ajax()) return;
57
58                                 goaway($a->get_baseurl(true) . '/admin/themes/' . $theme );
59                                 return;
60                                 break;
61                         case 'logs':
62                                 admin_page_logs_post($a);
63                                 break;
64                         case 'dbsync':
65                                 admin_page_dbsync_post($a);
66                                 break;
67                         case 'update':
68                                 admin_page_remoteupdate_post($a);
69                                 break;
70                 }
71         }
72
73         goaway($a->get_baseurl(true) . '/admin' );
74         return; // NOTREACHED   
75 }
76
77 /**
78  * @param App $a
79  * @return string
80  */
81 function admin_content(&$a) {
82
83         if(!is_site_admin()) {
84                 return login(false);
85         }
86
87         if(x($_SESSION,'submanage') && intval($_SESSION['submanage']))
88                 return "";
89
90         /**
91          * Side bar links
92          */
93
94         // array( url, name, extra css classes )
95         $aside = Array(
96                 'site'   =>     Array($a->get_baseurl(true)."/admin/site/", t("Site") , "site"),
97                 'users'  =>     Array($a->get_baseurl(true)."/admin/users/", t("Users") , "users"),
98                 'plugins'=>     Array($a->get_baseurl(true)."/admin/plugins/", t("Plugins") , "plugins"),
99                 'themes' =>     Array($a->get_baseurl(true)."/admin/themes/", t("Themes") , "themes"),
100                 'dbsync' => Array($a->get_baseurl(true)."/admin/dbsync/", t('DB updates'), "dbsync"),
101                 //'update' =>   Array($a->get_baseurl(true)."/admin/update/", t("Software Update") , "update")
102         );
103
104         /* get plugins admin page */
105
106         $r = q("SELECT * FROM `addon` WHERE `plugin_admin`=1");
107         $aside['plugins_admin']=Array();
108         foreach ($r as $h){
109                 $plugin =$h['name'];
110                 $aside['plugins_admin'][] = Array($a->get_baseurl(true)."/admin/plugins/".$plugin, $plugin, "plugin");
111                 // temp plugins with admin
112                 $a->plugins_admin[] = $plugin;
113         }
114
115         $aside['logs'] = Array($a->get_baseurl(true)."/admin/logs/", t("Logs"), "logs");
116
117         $t = get_markup_template("admin_aside.tpl");
118         $a->page['aside'] .= replace_macros( $t, array(
119                         '$admin' => $aside, 
120                         '$admtxt' => t('Admin'),
121                         '$plugadmtxt' => t('Plugin Features'),
122                         '$logtxt' => t('Logs'),
123                         '$h_pending' => t('User registrations waiting for confirmation'),
124                         '$admurl'=> $a->get_baseurl(true)."/admin/"
125         ));
126
127
128
129         /**
130          * Page content
131          */
132         $o = '';
133         // urls
134         if ($a->argc > 1){
135                 switch ($a->argv[1]){
136                         case 'site':
137                                 $o = admin_page_site($a);
138                                 break;
139                         case 'users':
140                                 $o = admin_page_users($a);
141                                 break;
142                         case 'plugins':
143                                 $o = admin_page_plugins($a);
144                                 break;
145                         case 'themes':
146                                 $o = admin_page_themes($a);
147                                 break;
148                         case 'logs':
149                                 $o = admin_page_logs($a);
150                                 break;
151                         case 'dbsync':
152                                 $o = admin_page_dbsync($a);
153                                 break;
154                         case 'update':
155                                 $o = admin_page_remoteupdate($a);
156                                 break;
157                         default:
158                                 notice( t("Item not found.") );
159                 }
160         } else {
161                 $o = admin_page_summary($a);
162         }
163
164         if(is_ajax()) {
165                 echo $o; 
166                 killme();
167                 return '';
168         } else {
169                 return $o;
170         }
171
172
173
174 /**
175  * Admin Summary Page
176  * @param App $a
177  * @return string
178  */
179 function admin_page_summary(&$a) {
180         $r = q("SELECT `page-flags`, COUNT(uid) as `count` FROM `user` GROUP BY `page-flags`");
181         $accounts = Array(
182                 Array( t('Normal Account'), 0),
183                 Array( t('Soapbox Account'), 0),
184                 Array( t('Community/Celebrity Account'), 0),
185                 Array( t('Automatic Friend Account'), 0),
186                 Array( t('Blog Account'), 0),
187                 Array( t('Private Forum'), 0)
188         );
189
190         $users=0;
191         foreach ($r as $u){ $accounts[$u['page-flags']][1] = $u['count']; $users+= $u['count']; }
192
193         logger('accounts: ' . print_r($accounts,true),LOGGER_DATA);
194
195         $r = q("SELECT COUNT(id) as `count` FROM `register`");
196         $pending = $r[0]['count'];
197                 
198         $r = q("select count(*) as total from deliverq where 1");
199         $deliverq = (($r) ? $r[0]['total'] : 0);
200
201         $r = q("select count(*) as total from queue where 1");
202         $queue = (($r) ? $r[0]['total'] : 0);
203
204         // We can do better, but this is a quick queue status
205
206         $queues = array( 'label' => t('Message queues'), 'deliverq' => $deliverq, 'queue' => $queue );
207
208
209         $t = get_markup_template("admin_summary.tpl");
210         return replace_macros($t, array(
211                 '$title' => t('Administration'),
212                 '$page' => t('Summary'),
213                 '$queues' => $queues,
214                 '$users' => Array( t('Registered users'), $users),
215                 '$accounts' => $accounts,
216                 '$pending' => Array( t('Pending registrations'), $pending),
217                 '$version' => Array( t('Version'), FRIENDICA_VERSION),
218                 '$build' =>  get_config('system','build'),
219                 '$plugins' => Array( t('Active plugins'), $a->plugins )
220         ));
221 }
222
223
224 /**
225  * Admin Site Page
226  *  @param App $a
227  */
228 function admin_page_site_post(&$a){
229         if (!x($_POST,"page_site")){
230                 return;
231         }
232
233         check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
234
235         $sitename               =       ((x($_POST,'sitename'))                 ? notags(trim($_POST['sitename']))              : '');
236         $banner                 =       ((x($_POST,'banner'))                   ? trim($_POST['banner'])                        : false);
237         $language               =       ((x($_POST,'language'))                 ? notags(trim($_POST['language']))              : '');
238         $theme                  =       ((x($_POST,'theme'))                    ? notags(trim($_POST['theme']))                 : '');
239         $theme_mobile           =       ((x($_POST,'theme_mobile'))             ? notags(trim($_POST['theme_mobile']))          : '');
240         $maximagesize           =       ((x($_POST,'maximagesize'))             ? intval(trim($_POST['maximagesize']))          :  0);
241         $maximagelength         =       ((x($_POST,'maximagelength'))           ? intval(trim($_POST['maximagelength']))        :  MAX_IMAGE_LENGTH);
242         $jpegimagequality       =       ((x($_POST,'jpegimagequality'))         ? intval(trim($_POST['jpegimagequality']))      :  JPEG_QUALITY);
243
244
245         $register_policy        =       ((x($_POST,'register_policy'))          ? intval(trim($_POST['register_policy']))       :  0);
246         $daily_registrations    =       ((x($_POST,'max_daily_registrations'))  ? intval(trim($_POST['max_daily_registrations']))       :0);
247         $abandon_days           =       ((x($_POST,'abandon_days'))             ? intval(trim($_POST['abandon_days']))          :  0);
248
249         $register_text          =       ((x($_POST,'register_text'))            ? notags(trim($_POST['register_text']))         : '');
250
251         $allowed_sites          =       ((x($_POST,'allowed_sites'))            ? notags(trim($_POST['allowed_sites']))         : '');
252         $allowed_email          =       ((x($_POST,'allowed_email'))            ? notags(trim($_POST['allowed_email']))         : '');
253         $block_public           =       ((x($_POST,'block_public'))             ? True                                          : False);
254         $force_publish          =       ((x($_POST,'publish_all'))              ? True                                          : False);
255         $global_directory       =       ((x($_POST,'directory_submit_url'))     ? notags(trim($_POST['directory_submit_url']))  : '');
256         $thread_allow           =       ((x($_POST,'thread_allow'))             ? True                                          : False);
257         $newuser_private                =       ((x($_POST,'newuser_private'))          ? True                                          : False);
258         $enotify_no_content             =       ((x($_POST,'enotify_no_content'))       ? True                                          : False);
259         $private_addons                 =       ((x($_POST,'private_addons'))           ? True                                          : False);
260         $disable_embedded               =       ((x($_POST,'disable_embedded'))         ? True                                          : False);
261         
262         $no_multi_reg           =       ((x($_POST,'no_multi_reg'))             ? True                                          : False);
263         $no_openid              =       !((x($_POST,'no_openid'))               ? True                                          : False);
264         $no_regfullname         =       !((x($_POST,'no_regfullname'))          ? True                                          : False);
265         $no_utf                 =       !((x($_POST,'no_utf'))                  ? True                                          : False);
266         $no_community_page      =       !((x($_POST,'no_community_page'))       ? True                                          : False);
267
268         $verifyssl              =       ((x($_POST,'verifyssl'))                ? True                                          : False);
269         $proxyuser              =       ((x($_POST,'proxyuser'))                ? notags(trim($_POST['proxyuser']))             : '');
270         $proxy                  =       ((x($_POST,'proxy'))                    ? notags(trim($_POST['proxy']))                 : '');
271         $timeout                =       ((x($_POST,'timeout'))                  ? intval(trim($_POST['timeout']))               : 60);
272         $delivery_interval      =       ((x($_POST,'delivery_interval'))        ? intval(trim($_POST['delivery_interval']))     : 0);
273         $poll_interval          =       ((x($_POST,'poll_interval'))            ? intval(trim($_POST['poll_interval']))         : 0);
274         $maxloadavg             =       ((x($_POST,'maxloadavg'))               ? intval(trim($_POST['maxloadavg']))            : 50);
275         $dfrn_only              =       ((x($_POST,'dfrn_only'))                ? True                                          : False);
276         $ostatus_disabled       =       !((x($_POST,'ostatus_disabled'))        ? True                                          : False);
277         $ostatus_poll_interval  =       ((x($_POST,'ostatus_poll_interval'))    ? intval(trim($_POST['ostatus_poll_interval']))         :  0);
278         $diaspora_enabled       =       ((x($_POST,'diaspora_enabled'))         ? True                                          : False);
279         $ssl_policy             =       ((x($_POST,'ssl_policy'))               ? intval($_POST['ssl_policy'])                  : 0);
280         $new_share              =       ((x($_POST,'new_share'))                ? True                                          : False);
281         $hide_help              =       ((x($_POST,'hide_help'))                ? True                                          : False);
282         $use_fulltext_engine    =       ((x($_POST,'use_fulltext_engine'))      ? True                                          : False);
283         $itemcache              =       ((x($_POST,'itemcache'))                ? notags(trim($_POST['itemcache']))             : '');
284         $itemcache_duration     =       ((x($_POST,'itemcache_duration'))       ? intval($_POST['itemcache_duration'])          : 0);
285         $lockpath               =       ((x($_POST,'lockpath'))                 ? notags(trim($_POST['lockpath']))              : '');
286         $temppath               =       ((x($_POST,'temppath'))                 ? notags(trim($_POST['temppath']))              : '');
287         $basepath               =       ((x($_POST,'basepath'))                 ? notags(trim($_POST['basepath']))              : '');
288         $singleuser             =       ((x($_POST,'singleuser'))               ? notags(trim($_POST['singleuser']))            : '');
289         if($ssl_policy != intval(get_config('system','ssl_policy'))) {
290                 if($ssl_policy == SSL_POLICY_FULL) {
291                         q("update `contact` set 
292                                 `url`     = replace(`url`    , 'http:' , 'https:'),
293                                 `photo`   = replace(`photo`  , 'http:' , 'https:'),
294                                 `thumb`   = replace(`thumb`  , 'http:' , 'https:'),
295                                 `micro`   = replace(`micro`  , 'http:' , 'https:'),
296                                 `request` = replace(`request`, 'http:' , 'https:'),
297                                 `notify`  = replace(`notify` , 'http:' , 'https:'),
298                                 `poll`    = replace(`poll`   , 'http:' , 'https:'),
299                                 `confirm` = replace(`confirm`, 'http:' , 'https:'),
300                                 `poco`    = replace(`poco`   , 'http:' , 'https:')
301                                 where `self` = 1"
302                         );
303                         q("update `profile` set 
304                                 `photo`   = replace(`photo`  , 'http:' , 'https:'),
305                                 `thumb`   = replace(`thumb`  , 'http:' , 'https:')
306                                 where 1 "
307                         );
308                 }
309                 elseif($ssl_policy == SSL_POLICY_SELFSIGN) {
310                         q("update `contact` set 
311                                 `url`     = replace(`url`    , 'https:' , 'http:'),
312                                 `photo`   = replace(`photo`  , 'https:' , 'http:'),
313                                 `thumb`   = replace(`thumb`  , 'https:' , 'http:'),
314                                 `micro`   = replace(`micro`  , 'https:' , 'http:'),
315                                 `request` = replace(`request`, 'https:' , 'http:'),
316                                 `notify`  = replace(`notify` , 'https:' , 'http:'),
317                                 `poll`    = replace(`poll`   , 'https:' , 'http:'),
318                                 `confirm` = replace(`confirm`, 'https:' , 'http:'),
319                                 `poco`    = replace(`poco`   , 'https:' , 'http:')
320                                 where `self` = 1"
321                         );
322                         q("update `profile` set 
323                                 `photo`   = replace(`photo`  , 'https:' , 'http:'),
324                                 `thumb`   = replace(`thumb`  , 'https:' , 'http:')
325                                 where 1 "
326                         );
327                 }
328         }
329         set_config('system','ssl_policy',$ssl_policy);
330         set_config('system','delivery_interval',$delivery_interval);
331         set_config('system','poll_interval',$poll_interval);
332         set_config('system','maxloadavg',$maxloadavg);
333         set_config('config','sitename',$sitename);
334         if ($banner==""){
335                 // don't know why, but del_config doesn't work...
336                 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
337                         dbesc("system"),
338                         dbesc("banner")
339                 );
340         } else {
341                 set_config('system','banner', $banner);
342         }
343         set_config('system','language', $language);
344         set_config('system','theme', $theme);
345         if ( $theme_mobile === '---' ) {
346                 del_config('system','mobile-theme');
347         } else {
348                 set_config('system','mobile-theme', $theme_mobile);
349         }
350         if ( $singleuser === '---' ) {
351             del_config('system','singleuser');
352         } else {
353             set_config('system','singleuser', $singleuser);
354         }
355         set_config('system','maximagesize', $maximagesize);
356         set_config('system','max_image_length', $maximagelength);
357         set_config('system','jpeg_quality', $jpegimagequality);
358         
359         set_config('config','register_policy', $register_policy);
360         set_config('system','max_daily_registrations', $daily_registrations);
361         set_config('system','account_abandon_days', $abandon_days);
362         set_config('config','register_text', $register_text);
363         set_config('system','allowed_sites', $allowed_sites);
364         set_config('system','allowed_email', $allowed_email);
365         set_config('system','block_public', $block_public);
366         set_config('system','publish_all', $force_publish);
367         if ($global_directory==""){
368                 // don't know why, but del_config doesn't work...
369                 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
370                         dbesc("system"),
371                         dbesc("directory_submit_url")
372                 );
373         } else {
374                 set_config('system','directory_submit_url', $global_directory);
375         }
376         set_config('system','thread_allow', $thread_allow);
377         set_config('system','newuser_private', $newuser_private);
378         set_config('system','enotify_no_content', $enotify_no_content);
379         set_config('system','disable_embedded', $disable_embedded);
380
381         set_config('system','block_extended_register', $no_multi_reg);
382         set_config('system','no_openid', $no_openid);
383         set_config('system','no_regfullname', $no_regfullname);
384         set_config('system','no_community_page', $no_community_page);
385         set_config('system','no_utf', $no_utf);
386         set_config('system','verifyssl', $verifyssl);
387         set_config('system','proxyuser', $proxyuser);
388         set_config('system','proxy', $proxy);
389         set_config('system','curl_timeout', $timeout);
390         set_config('system','dfrn_only', $dfrn_only);
391         set_config('system','ostatus_disabled', $ostatus_disabled);
392         set_config('system','ostatus_poll_interval', $ostatus_poll_interval);
393         set_config('system','diaspora_enabled', $diaspora_enabled);
394         set_config('config','private_addons', $private_addons);
395         
396         set_config('system','new_share', $new_share);
397         set_config('system','hide_help', $hide_help);
398         set_config('system','use_fulltext_engine', $use_fulltext_engine);
399         set_config('system','itemcache', $itemcache);
400         set_config('system','itemcache_duration', $itemcache_duration);
401         set_config('system','lockpath', $lockpath);
402         set_config('system','temppath', $temppath);
403         set_config('system','basepath', $basepath);
404         
405         info( t('Site settings updated.') . EOL);
406         goaway($a->get_baseurl(true) . '/admin/site' );
407         return; // NOTREACHED
408
409 }
410
411 /**
412  * @param  App $a
413  * @return string
414  */
415 function admin_page_site(&$a) {
416         
417         /* Installed langs */
418         $lang_choices = array();
419         $langs = glob('view/*/strings.php');
420         
421         if(is_array($langs) && count($langs)) {
422                 if(! in_array('view/en/strings.php',$langs))
423                         $langs[] = 'view/en/';
424                 asort($langs);
425                 foreach($langs as $l) {
426                         $t = explode("/",$l);
427                         $lang_choices[$t[1]] = $t[1];
428                 }
429         }
430         
431         /* Installed themes */
432         $theme_choices = array();
433         $theme_choices_mobile = array();
434         $theme_choices_mobile["---"] = t("No special theme for mobile devices");
435         $files = glob('view/theme/*');
436         if($files) {
437                 foreach($files as $file) {
438                         $f = basename($file);
439                         $theme_name = ((file_exists($file . '/experimental')) ?  sprintf("%s - \x28Experimental\x29", $f) : $f);
440             if (file_exists($file . '/mobile')) {
441                 $theme_choices_mobile[$f] = $theme_name;
442             }
443                 else {
444                 $theme_choices[$f] = $theme_name;
445                         }
446                 }
447         }
448
449         /* OStatus conversation poll choices */
450         $ostatus_poll_choices = array(
451                 "-1" => t("Never"),
452                 "0" => t("Frequently"),
453                 "60" => t("Hourly"),
454                 "720" => t("Twice daily"),
455                 "1440" => t("Daily")
456             );
457
458         /* get user names to make the install a personal install of X */
459         $user_names = array();
460         $user_names['---'] = t('Multi user instance');
461         $users = q("SELECT username, nickname FROM `user`");
462         foreach ($users as $user) {
463             $user_names[$user['nickname']] = $user['username'];
464         }
465
466         /* Banner */
467         $banner = get_config('system','banner');
468         if($banner == false) 
469                 $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>';
470         $banner = htmlspecialchars($banner);
471
472         //echo "<pre>"; var_dump($lang_choices); die("</pre>");
473
474         /* Register policy */
475         $register_choices = Array(
476                 REGISTER_CLOSED => t("Closed"),
477                 REGISTER_APPROVE => t("Requires approval"),
478                 REGISTER_OPEN => t("Open")
479         ); 
480
481         $ssl_choices = array(
482                 SSL_POLICY_NONE => t("No SSL policy, links will track page SSL state"),
483                 SSL_POLICY_FULL => t("Force all links to use SSL"),
484                 SSL_POLICY_SELFSIGN => t("Self-signed certificate, use SSL for local links only (discouraged)")
485         );
486
487         $t = get_markup_template("admin_site.tpl");
488         return replace_macros($t, array(
489                 '$title' => t('Administration'),
490                 '$page' => t('Site'),
491                 '$submit' => t('Submit'),
492                 '$registration' => t('Registration'),
493                 '$upload' => t('File upload'),
494                 '$corporate' => t('Policies'),
495                 '$advanced' => t('Advanced'),
496                 '$performance' => t('Performance'),
497                 
498                 '$baseurl' => $a->get_baseurl(true),
499                 // name, label, value, help string, extra data...
500                 '$sitename'             => array('sitename', t("Site name"), htmlentities($a->config['sitename'], ENT_QUOTES), 'UTF-8'),
501                 '$banner'               => array('banner', t("Banner/Logo"), $banner, ""),
502                 '$language'             => array('language', t("System language"), get_config('system','language'), "", $lang_choices),
503                 '$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),
504                 '$theme_mobile'         => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile-theme'), t("Theme for mobile devices"), $theme_choices_mobile),
505                 '$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),
506                 '$new_share'            => array('new_share', t("'Share' element"), get_config('system','new_share'), t("Activates the bbcode element 'share' for repeating items.")),
507                 '$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.")),
508                 '$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),
509                 '$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.")),
510                 '$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.")),
511                 '$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.")),
512
513                 '$register_policy'      => array('register_policy', t("Register policy"), $a->config['register_policy'], "", $register_choices),
514                 '$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.")),
515                 '$register_text'        => array('register_text', t("Register text"), htmlentities($a->config['register_text'], ENT_QUOTES, 'UTF-8'), t("Will be displayed prominently on the registration page.")),
516                 '$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.')),
517                 '$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")),
518                 '$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")),
519                 '$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.")),
520                 '$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.")),
521                 '$global_directory'     => array('directory_submit_url', t("Global directory update URL"), get_config('system','directory_submit_url'), t("URL to update the global directory. If this is not set, the global directory is completely unavailable to the application.")),
522                 '$thread_allow'         => array('thread_allow', t("Allow threaded items"), get_config('system','thread_allow'), t("Allow infinite level threading for items on this site.")),
523                 '$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.")),
524                 '$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.")),
525                 '$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.")),
526                 '$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.")),
527                 
528                 '$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.")),
529                 '$no_openid'            => array('no_openid', t("OpenID support"), !get_config('system','no_openid'), t("OpenID support for registration and logins.")),
530                 '$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")),
531                 '$no_utf'               => array('no_utf', t("UTF-8 Regular expressions"), !get_config('system','no_utf'), t("Use PHP UTF8 regular expressions")),
532                 '$no_community_page'    => array('no_community_page', t("Show Community Page"), !get_config('system','no_community_page'), t("Display a Community page showing all recent public postings on this site.")),
533                 '$ostatus_disabled'     => array('ostatus_disabled', t("Enable OStatus support"), !get_config('system','ostatus_disabled'), t("Provide built-in OStatus \x28identi.ca, status.net, etc.\x29 compatibility. All communications in OStatus are public, so privacy warnings will be occasionally displayed.")),    
534                 '$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),
535                 '$diaspora_enabled'     => array('diaspora_enabled', t("Enable Diaspora support"), get_config('system','diaspora_enabled'), t("Provide built-in Diaspora network compatibility.")),     
536                 '$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.")),
537                 '$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.")),
538                 '$proxyuser'            => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""),
539                 '$proxy'                => array('proxy', t("Proxy URL"), get_config('system','proxy'), ""),
540                 '$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).")),
541                 '$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.")),
542                 '$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.")),
543                 '$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.")),
544
545                 '$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.")),
546                 '$itemcache'            => array('itemcache', t("Path to item cache"), get_config('system','itemcache'), "The item caches buffers generated bbcode and external images."),
547                 '$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).")),
548                 '$lockpath'             => array('lockpath', t("Path for lock file"), get_config('system','lockpath'), "The lock file is used to avoid multiple pollers at one time. Only define a folder here."),
549                 '$temppath'             => array('temppath', t("Temp path"), get_config('system','temppath'), "If you have a restricted system where the webserver can't access the system temp path, enter another path here."),
550                 '$basepath'             => array('basepath', t("Base path to installation"), get_config('system','basepath'), "If the system cannot detect the correct path to your installation, enter the correct path here. This setting should only be set if you are using a restricted system and symbolic links to your webroot."),
551         '$form_security_token' => get_form_security_token("admin_site"),
552
553         ));
554
555 }
556
557
558 function admin_page_dbsync(&$a) {
559
560         $o = '';
561
562         if($a->argc > 3 && intval($a->argv[3]) && $a->argv[2] === 'mark') {
563                 set_config('database', 'update_' . intval($a->argv[3]), 'success');
564                 $curr = get_config('system','build');
565                 if(intval($curr) == intval($a->argv[3]))
566                         set_config('system','build',intval($curr) + 1);
567                 info( t('Update has been marked successful') . EOL);
568                 goaway($a->get_baseurl(true) . '/admin/dbsync');
569         }
570
571         if($a->argc > 2 && intval($a->argv[2])) {
572                 require_once('update.php');
573                 $func = 'update_' . intval($a->argv[2]);
574                 if(function_exists($func)) {
575                         $retval = $func();
576                         if($retval === UPDATE_FAILED) {
577                                 $o .= sprintf( t('Executing %s failed. Check system logs.'), $func); 
578                         }
579                         elseif($retval === UPDATE_SUCCESS) {
580                                 $o .= sprintf( t('Update %s was successfully applied.', $func));
581                                 set_config('database',$func, 'success');
582                         }
583                         else
584                                 $o .= sprintf( t('Update %s did not return a status. Unknown if it succeeded.'), $func);
585                 }
586                 else
587                         $o .= sprintf( t('Update function %s could not be found.'), $func);
588                 return $o;
589         }
590
591         $failed = array();
592         $r = q("select * from config where `cat` = 'database' ");
593         if(count($r)) {
594                 foreach($r as $rr) {
595                         $upd = intval(substr($rr['k'],7));
596                         if($upd < 1139 || $rr['v'] === 'success')
597                                 continue;
598                         $failed[] = $upd;
599                 }
600         }
601         if(! count($failed))
602                 return '<h3>' . t('No failed updates.') . '</h3>';
603
604         $o = replace_macros(get_markup_template('failed_updates.tpl'),array(
605                 '$base' => $a->get_baseurl(true),
606                 '$banner' => t('Failed Updates'),
607                 '$desc' => t('This does not include updates prior to 1139, which did not return a status.'),
608                 '$mark' => t('Mark success (if update was manually applied)'),
609                 '$apply' => t('Attempt to execute this update step automatically'),
610                 '$failed' => $failed
611         ));     
612
613         return $o;
614
615 }
616
617 /**
618  * Users admin page
619  *
620  * @param App $a
621  */
622 function admin_page_users_post(&$a){
623         $pending = ( x($_POST, 'pending') ? $_POST['pending'] : Array() );
624         $users = ( x($_POST, 'user') ? $_POST['user'] : Array() );
625
626     check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
627
628         if (x($_POST,'page_users_block')){
629                 foreach($users as $uid){
630                         q("UPDATE `user` SET `blocked`=1-`blocked` WHERE `uid`=%s",
631                                 intval( $uid )
632                         );
633                 }
634                 notice( sprintf( tt("%s user blocked/unblocked", "%s users blocked/unblocked", count($users)), count($users)) );
635         }
636         if (x($_POST,'page_users_delete')){
637                 require_once("include/Contact.php");
638                 foreach($users as $uid){
639                         user_remove($uid);
640                 }
641                 notice( sprintf( tt("%s user deleted", "%s users deleted", count($users)), count($users)) );
642         }
643         
644         if (x($_POST,'page_users_approve')){
645                 require_once("mod/regmod.php");
646                 foreach($pending as $hash){
647                         user_allow($hash);
648                 }
649         }
650         if (x($_POST,'page_users_deny')){
651                 require_once("mod/regmod.php");
652                 foreach($pending as $hash){
653                         user_deny($hash);
654                 }
655         }
656         goaway($a->get_baseurl(true) . '/admin/users' );
657         return; // NOTREACHED   
658 }
659
660 /**
661  * @param App $a
662  * @return string
663  */
664 function admin_page_users(&$a){
665         if ($a->argc>2) {
666                 $uid = $a->argv[3];
667                 $user = q("SELECT * FROM `user` WHERE `uid`=%d", intval($uid));
668                 if (count($user)==0){
669                         notice( 'User not found' . EOL);
670                         goaway($a->get_baseurl(true) . '/admin/users' );
671                         return ''; // NOTREACHED
672                 }               
673                 switch($a->argv[2]){
674                         case "delete":{
675                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
676                                 // delete user
677                                 require_once("include/Contact.php");
678                                 user_remove($uid);
679                                 
680                                 notice( sprintf(t("User '%s' deleted"), $user[0]['username']) . EOL);
681                         }; break;
682                         case "block":{
683                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
684                                 q("UPDATE `user` SET `blocked`=%d WHERE `uid`=%s",
685                                         intval( 1-$user[0]['blocked'] ),
686                                         intval( $uid )
687                                 );
688                                 notice( sprintf( ($user[0]['blocked']?t("User '%s' unblocked"):t("User '%s' blocked")) , $user[0]['username']) . EOL);
689                         }; break;
690                 }
691                 goaway($a->get_baseurl(true) . '/admin/users' );
692                 return ''; // NOTREACHED
693                 
694         }
695         
696         /* get pending */
697         $pending = q("SELECT `register`.*, `contact`.`name`, `user`.`email`
698                                  FROM `register`
699                                  LEFT JOIN `contact` ON `register`.`uid` = `contact`.`uid`
700                                  LEFT JOIN `user` ON `register`.`uid` = `user`.`uid`;");
701         
702         
703         /* get users */
704
705         $total = q("SELECT count(*) as total FROM `user` where 1");
706         if(count($total)) {
707                 $a->set_pager_total($total[0]['total']);
708                 $a->set_pager_itemspage(100);
709         }
710         
711         
712         $users = q("SELECT `user` . * , `contact`.`name` , `contact`.`url` , `contact`.`micro`, `lastitem`.`lastitem_date`, `user`.`account_expired`
713                                 FROM
714                                         (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid`
715                                         FROM `item`
716                                         WHERE `item`.`type` = 'wall'
717                                         GROUP BY `item`.`uid`) AS `lastitem`
718                                                  RIGHT OUTER JOIN `user` ON `user`.`uid` = `lastitem`.`uid`,
719                                            `contact`
720                                 WHERE
721                                            `user`.`uid` = `contact`.`uid`
722                                                 AND `user`.`verified` =1
723                                         AND `contact`.`self` =1
724                                 ORDER BY `contact`.`name` LIMIT %d, %d
725                                 ",
726                                 intval($a->pager['start']),
727                                 intval($a->pager['itemspage'])
728                                 );
729                                         
730         function _setup_users($e){
731         $a = get_app();
732                 $accounts = Array(
733                         t('Normal Account'), 
734                         t('Soapbox Account'),
735                         t('Community/Celebrity Account'),
736                         t('Automatic Friend Account')
737                 );
738                 $e['page-flags'] = $accounts[$e['page-flags']];
739                 $e['register_date'] = relative_date($e['register_date']);
740                 $e['login_date'] = relative_date($e['login_date']);
741                 $e['lastitem_date'] = relative_date($e['lastitem_date']);
742         $e['is_admin'] = ($e['email'] === $a->config['admin_email']);
743                 return $e;
744         }
745         $users = array_map("_setup_users", $users);
746         
747         
748         // Get rid of dashes in key names, Smarty3 can't handle them
749         foreach($users as $key => $user) {
750                 $new_user = array();
751                 foreach($user as $k => $v) {
752                         $k = str_replace('-','_',$k);
753                         $new_user[$k] = $v;
754                 }
755                 $users[$key] = $new_user;
756         }
757
758         $t = get_markup_template("admin_users.tpl");
759         $o = replace_macros($t, array(
760                 // strings //
761                 '$title' => t('Administration'),
762                 '$page' => t('Users'),
763                 '$submit' => t('Submit'),
764                 '$select_all' => t('select all'),
765                 '$h_pending' => t('User registrations waiting for confirm'),
766                 '$th_pending' => array( t('Request date'), t('Name'), t('Email') ),
767                 '$no_pending' =>  t('No registrations.'),
768                 '$approve' => t('Approve'),
769                 '$deny' => t('Deny'),
770                 '$delete' => t('Delete'),
771                 '$block' => t('Block'),
772                 '$unblock' => t('Unblock'),
773         '$siteadmin' => t('Site admin'),
774         '$accountexpired' => t('Account expired'),
775                 
776                 '$h_users' => t('Users'),
777                 '$th_users' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'),  t('Account') ),
778
779                 '$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?'),
780                 '$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?'),
781
782         '$form_security_token' => get_form_security_token("admin_users"),
783
784                 // values //
785                 '$baseurl' => $a->get_baseurl(true),
786
787                 '$pending' => $pending,
788                 '$users' => $users,
789         ));
790         $o .= paginate($a);
791         return $o;
792 }
793
794
795 /**
796  * Plugins admin page
797  *
798  * @param App $a
799  * @return string
800  */
801 function admin_page_plugins(&$a){
802
803         /**
804          * Single plugin
805          */
806         if ($a->argc == 3){
807                 $plugin = $a->argv[2];
808                 if (!is_file("addon/$plugin/$plugin.php")){
809                         notice( t("Item not found.") );
810                         return '';
811                 }
812
813                 if (x($_GET,"a") && $_GET['a']=="t"){
814                         check_form_security_token_redirectOnErr('/admin/plugins', 'admin_themes', 't');
815
816                         // Toggle plugin status
817                         $idx = array_search($plugin, $a->plugins);
818                         if ($idx !== false){
819                                 unset($a->plugins[$idx]);
820                                 uninstall_plugin($plugin);
821                                 info( sprintf( t("Plugin %s disabled."), $plugin ) );
822                         } else {
823                                 $a->plugins[] = $plugin;
824                                 install_plugin($plugin);
825                                 info( sprintf( t("Plugin %s enabled."), $plugin ) );
826                         }
827                         set_config("system","addon", implode(", ",$a->plugins));
828                         goaway($a->get_baseurl(true) . '/admin/plugins' );
829                         return ''; // NOTREACHED
830                 }
831                 // display plugin details
832                 require_once('library/markdown.php');
833
834                 if (in_array($plugin, $a->plugins)){
835                         $status="on"; $action= t("Disable");
836                 } else {
837                         $status="off"; $action= t("Enable");
838                 }
839
840                 $readme=Null;
841                 if (is_file("addon/$plugin/README.md")){
842                         $readme = file_get_contents("addon/$plugin/README.md");
843                         $readme = Markdown($readme);
844                 } else if (is_file("addon/$plugin/README")){
845                         $readme = "<pre>". file_get_contents("addon/$plugin/README") ."</pre>";
846                 }
847
848                 $admin_form="";
849                 if (is_array($a->plugins_admin) && in_array($plugin, $a->plugins_admin)){
850                         @require_once("addon/$plugin/$plugin.php");
851                         $func = $plugin.'_plugin_admin';
852                         $func($a, $admin_form);
853                 }
854
855                 $t = get_markup_template("admin_plugins_details.tpl");
856
857                 return replace_macros($t, array(
858                         '$title' => t('Administration'),
859                         '$page' => t('Plugins'),
860                         '$toggle' => t('Toggle'),
861                         '$settings' => t('Settings'),
862                         '$baseurl' => $a->get_baseurl(true),
863
864                         '$plugin' => $plugin,
865                         '$status' => $status,
866                         '$action' => $action,
867                         '$info' => get_plugin_info($plugin),
868                         '$str_author' => t('Author: '),
869                         '$str_maintainer' => t('Maintainer: '),
870
871                         '$admin_form' => $admin_form,
872                         '$function' => 'plugins',
873                         '$screenshot' => '',
874                         '$readme' => $readme,
875
876                         '$form_security_token' => get_form_security_token("admin_themes"),
877                 ));
878         }
879
880
881
882         /**
883          * List plugins
884          */
885
886         $plugins = array();
887         $files = glob("addon/*/");
888         if($files) {
889                 foreach($files as $file) {      
890                         if (is_dir($file)){
891                                 list($tmp, $id)=array_map("trim", explode("/",$file));
892                                 $info = get_plugin_info($id);
893                                 $plugins[] = array( $id, (in_array($id,  $a->plugins)?"on":"off") , $info);
894                         }
895                 }
896         }
897
898         $t = get_markup_template("admin_plugins.tpl");
899         return replace_macros($t, array(
900                 '$title' => t('Administration'),
901                 '$page' => t('Plugins'),
902                 '$submit' => t('Submit'),
903                 '$baseurl' => $a->get_baseurl(true),
904                 '$function' => 'plugins',       
905                 '$plugins' => $plugins,
906         '$form_security_token' => get_form_security_token("admin_themes"),
907         ));
908 }
909
910 /**
911  * @param array $themes
912  * @param string $th
913  * @param int $result
914  */
915 function toggle_theme(&$themes,$th,&$result) {
916         for($x = 0; $x < count($themes); $x ++) {
917                 if($themes[$x]['name'] === $th) {
918                         if($themes[$x]['allowed']) {
919                                 $themes[$x]['allowed'] = 0;
920                                 $result = 0;
921                         }
922                         else {
923                                 $themes[$x]['allowed'] = 1;
924                                 $result = 1;
925                         }
926                 }
927         }
928 }
929
930 /**
931  * @param array $themes
932  * @param string $th
933  * @return int
934  */
935 function theme_status($themes,$th) {
936         for($x = 0; $x < count($themes); $x ++) {
937                 if($themes[$x]['name'] === $th) {
938                         if($themes[$x]['allowed']) {
939                                 return 1;
940                         }
941                         else {
942                                 return 0;
943                         }
944                 }
945         }
946         return 0;
947 }
948
949
950 /**
951  * @param array $themes
952  * @return string
953  */
954 function rebuild_theme_table($themes) {
955         $o = '';
956         if(count($themes)) {
957                 foreach($themes as $th) {
958                         if($th['allowed']) {
959                                 if(strlen($o))
960                                         $o .= ',';
961                                 $o .= $th['name'];
962                         }
963                 }
964         }
965         return $o;
966 }
967
968
969 /**
970  * Themes admin page
971  *
972  * @param App $a
973  * @return string
974  */
975 function admin_page_themes(&$a){
976
977         $allowed_themes_str = get_config('system','allowed_themes');
978         $allowed_themes_raw = explode(',',$allowed_themes_str);
979         $allowed_themes = array();
980         if(count($allowed_themes_raw))
981                 foreach($allowed_themes_raw as $x)
982                         if(strlen(trim($x)))
983                                 $allowed_themes[] = trim($x);
984
985         $themes = array();
986     $files = glob('view/theme/*');
987     if($files) {
988         foreach($files as $file) {
989             $f = basename($file);
990             $is_experimental = intval(file_exists($file . '/experimental'));
991                         $is_supported = 1-(intval(file_exists($file . '/unsupported'))); // Is not used yet
992                         $is_allowed = intval(in_array($f,$allowed_themes));
993                         $themes[] = array('name' => $f, 'experimental' => $is_experimental, 'supported' => $is_supported, 'allowed' => $is_allowed);
994         }
995     }
996
997         if(! count($themes)) {
998                 notice( t('No themes found.'));
999                 return '';
1000         }
1001
1002         /**
1003          * Single theme
1004          */
1005
1006         if ($a->argc == 3){
1007                 $theme = $a->argv[2];
1008                 if(! is_dir("view/theme/$theme")){
1009                         notice( t("Item not found.") );
1010                         return '';
1011                 }
1012
1013                 if (x($_GET,"a") && $_GET['a']=="t"){
1014                         check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't');
1015
1016                         // Toggle theme status
1017
1018                         toggle_theme($themes,$theme,$result);
1019                         $s = rebuild_theme_table($themes);
1020                         if($result) {
1021                                 install_theme($theme);
1022                                 info( sprintf('Theme %s enabled.',$theme));
1023                         }
1024                         else {
1025                                 uninstall_theme($theme);
1026                                 info( sprintf('Theme %s disabled.',$theme));
1027                         }
1028
1029                         set_config('system','allowed_themes',$s);
1030                         goaway($a->get_baseurl(true) . '/admin/themes' );
1031                         return ''; // NOTREACHED
1032                 }
1033
1034                 // display theme details
1035                 require_once('library/markdown.php');
1036
1037                 if (theme_status($themes,$theme)) {
1038                         $status="on"; $action= t("Disable");
1039                 } else {
1040                         $status="off"; $action= t("Enable");
1041                 }
1042
1043                 $readme=Null;
1044                 if (is_file("view/theme/$theme/README.md")){
1045                         $readme = file_get_contents("view/theme/$theme/README.md");
1046                         $readme = Markdown($readme);
1047                 } else if (is_file("view/theme/$theme/README")){
1048                         $readme = "<pre>". file_get_contents("view/theme/$theme/README") ."</pre>";
1049                 }
1050
1051                 $admin_form="";
1052                 if (is_file("view/theme/$theme/config.php")){
1053                         require_once("view/theme/$theme/config.php");
1054                         if(function_exists("theme_admin")){
1055                                 $admin_form = theme_admin($a);
1056                         }
1057
1058                 }
1059
1060                 $screenshot = array( get_theme_screenshot($theme), t('Screenshot'));
1061                 if(! stristr($screenshot[0],$theme))
1062                         $screenshot = null;
1063
1064                 $t = get_markup_template("admin_plugins_details.tpl");
1065                 return replace_macros($t, array(
1066                         '$title' => t('Administration'),
1067                         '$page' => t('Themes'),
1068                         '$toggle' => t('Toggle'),
1069                         '$settings' => t('Settings'),
1070                         '$baseurl' => $a->get_baseurl(true),
1071
1072                         '$plugin' => $theme,
1073                         '$status' => $status,
1074                         '$action' => $action,
1075                         '$info' => get_theme_info($theme),
1076                         '$function' => 'themes',
1077                         '$admin_form' => $admin_form,
1078                         '$str_author' => t('Author: '),
1079                         '$str_maintainer' => t('Maintainer: '),
1080                         '$screenshot' => $screenshot,
1081                         '$readme' => $readme,
1082
1083                         '$form_security_token' => get_form_security_token("admin_themes"),
1084                 ));
1085         }
1086
1087         /**
1088          * List themes
1089          */
1090
1091         $xthemes = array();
1092         if($themes) {
1093                 foreach($themes as $th) {
1094                         $xthemes[] = array($th['name'],(($th['allowed']) ? "on" : "off"), get_theme_info($th['name']));
1095                 }
1096         }
1097
1098         $t = get_markup_template("admin_plugins.tpl");
1099         return replace_macros($t, array(
1100                 '$title' => t('Administration'),
1101                 '$page' => t('Themes'),
1102                 '$submit' => t('Submit'),
1103                 '$baseurl' => $a->get_baseurl(true),
1104                 '$function' => 'themes',
1105                 '$plugins' => $xthemes,
1106                 '$experimental' => t('[Experimental]'),
1107                 '$unsupported' => t('[Unsupported]'),
1108         '$form_security_token' => get_form_security_token("admin_themes"),
1109         ));
1110 }
1111
1112
1113 /**
1114  * Logs admin page
1115  *
1116  * @param App $a
1117  */
1118  
1119 function admin_page_logs_post(&$a) {
1120         if (x($_POST,"page_logs")) {
1121         check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
1122
1123                 $logfile                =       ((x($_POST,'logfile'))          ? notags(trim($_POST['logfile']))       : '');
1124                 $debugging              =       ((x($_POST,'debugging'))        ? true                                                          : false);
1125                 $loglevel               =       ((x($_POST,'loglevel'))         ? intval(trim($_POST['loglevel']))      : 0);
1126
1127                 set_config('system','logfile', $logfile);
1128                 set_config('system','debugging',  $debugging);
1129                 set_config('system','loglevel', $loglevel);
1130
1131                 
1132         }
1133
1134         info( t("Log settings updated.") );
1135         goaway($a->get_baseurl(true) . '/admin/logs' );
1136         return; // NOTREACHED   
1137 }
1138
1139 /**
1140  * @param App $a
1141  * @return string
1142  */
1143 function admin_page_logs(&$a){
1144         
1145         $log_choices = Array(
1146                 LOGGER_NORMAL => 'Normal',
1147                 LOGGER_TRACE => 'Trace',
1148                 LOGGER_DEBUG => 'Debug',
1149                 LOGGER_DATA => 'Data',
1150                 LOGGER_ALL => 'All'
1151         );
1152         
1153         $t = get_markup_template("admin_logs.tpl");
1154
1155         $f = get_config('system','logfile');
1156
1157         $data = '';
1158
1159         if(!file_exists($f)) {
1160                 $data = t("Error trying to open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f exist and is 
1161 readable.");
1162         }
1163         else {
1164                 $fp = fopen($f, 'r');
1165                 if(!$fp) {
1166                         $data = t("Couldn't open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f is readable.");
1167                 }
1168                 else {
1169                         $fstat = fstat($fp);
1170                         $size = $fstat['size'];
1171                         if($size != 0)
1172                         {
1173                                 if($size > 5000000 || $size < 0)
1174                                         $size = 5000000;
1175                                 $seek = fseek($fp,0-$size,SEEK_END);
1176                                 if($seek === 0) {
1177                                         $data = escape_tags(fread($fp,$size));
1178                                         while(! feof($fp))
1179                                                 $data .= escape_tags(fread($fp,4096));
1180                                 }
1181                         }
1182                         fclose($fp);
1183                 }
1184         }                       
1185
1186         return replace_macros($t, array(
1187                 '$title' => t('Administration'),
1188                 '$page' => t('Logs'),
1189                 '$submit' => t('Submit'),
1190                 '$clear' => t('Clear'),
1191                 '$data' => $data,
1192                 '$baseurl' => $a->get_baseurl(true),
1193                 '$logname' =>  get_config('system','logfile'),
1194                 
1195                                                                         // name, label, value, help string, extra data...
1196                 '$debugging'            => array('debugging', t("Enable Debugging"),get_config('system','debugging'), ""),
1197                 '$logfile'                      => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Friendica top-level directory.")),
1198                 '$loglevel'             => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices),
1199
1200         '$form_security_token' => get_form_security_token("admin_logs"),
1201         ));
1202 }
1203
1204 /**
1205  * @param App $a
1206  */
1207 function admin_page_remoteupdate_post(&$a) {
1208         // this function should be called via ajax post
1209         if(!is_site_admin()) {
1210                 return;
1211         }
1212
1213         
1214         if (x($_POST,'remotefile') && $_POST['remotefile']!=""){
1215                 $remotefile = $_POST['remotefile'];
1216                 $ftpdata = (x($_POST['ftphost'])?$_POST:false);
1217                 doUpdate($remotefile, $ftpdata);
1218         } else {
1219                 echo "No remote file to download. Abort!";
1220         }
1221
1222         killme();
1223 }
1224
1225 /**
1226  * @param App $a
1227  * @return string
1228  */
1229 function admin_page_remoteupdate(&$a) {
1230         if(!is_site_admin()) {
1231                 return login(false);
1232         }
1233
1234         $canwrite = canWeWrite();
1235         $canftp = function_exists('ftp_connect');
1236         
1237         $needupdate = true;
1238         $u = checkUpdate();
1239         if (!is_array($u)){
1240                 $needupdate = false;
1241                 $u = array('','','');
1242         }
1243         
1244         $tpl = get_markup_template("admin_remoteupdate.tpl");
1245         return replace_macros($tpl, array(
1246                 '$baseurl' => $a->get_baseurl(true),
1247                 '$submit' => t("Update now"),
1248                 '$close' => t("Close"),
1249                 '$localversion' => FRIENDICA_VERSION,
1250                 '$remoteversion' => $u[1],
1251                 '$needupdate' => $needupdate,
1252                 '$canwrite' => $canwrite,
1253                 '$canftp'       => $canftp,
1254                 '$ftphost'      => array('ftphost', t("FTP Host"), '',''),
1255                 '$ftppath'      => array('ftppath', t("FTP Path"), '/',''),
1256                 '$ftpuser'      => array('ftpuser', t("FTP User"), '',''),
1257                 '$ftppwd'       => array('ftppwd', t("FTP Password"), '',''),
1258                 '$remotefile'=>array('remotefile','', $u['2'],''),
1259         ));
1260         
1261 }