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