]> git.mxchange.org Git - friendica.git/blob - mod/admin.php
Adding a "User waiting for permanent deletion" table in admin page
[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         $nu_name = ( x($_POST, 'new_user_name') ? $_POST['new_user_name'] : ''); 
626   $nu_nickname = ( x($_POST, 'new_user_nickname') ? $_POST['new_user_nickname'] : ''); 
627   $nu_email = ( x($_POST, 'new_user_email') ? $_POST['new_user_email'] : '');
628
629   check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
630     
631   if (!($nu_name==="") && !($nu_email==="") && !($nu_nickname==="")) { 
632       require_once('include/user.php'); 
633       require_once('include/email.php'); 
634       $result = create_user( array('username'=>$nu_name, 'email'=>$nu_email, 'nickname'=>$nu_nickname, 'verified'=>1)  ); 
635       if(! $result['success']) { 
636                     notice($result['message']); 
637                     return; 
638       } 
639       $nu = $result['user']; 
640       $email_tpl = get_intltext_template("register_adminadd_eml.tpl"); 
641       $email_tpl = replace_macros($email_tpl, array( 
642                     '$sitename' => $a->config['sitename'], 
643                     '$siteurl' =>  $a->get_baseurl(), 
644                     '$username' => $nu['username'], 
645                     '$email' => $nu['email'], 
646                     '$password' => $result['password'], 
647                     '$uid' => $nu['uid'] )); 
648  
649       $res = mail($nu['email'], email_header_encode( sprintf( t('Registration details for %s'), $a->config['sitename']),'UTF-8'), 
650                     $email_tpl,  
651                     'From: ' . 'Administrator' . '@' . $_SERVER['SERVER_NAME'] . "\n" 
652                     . 'Content-type: text/plain; charset=UTF-8' . "\n" 
653                     . 'Content-transfer-encoding: 8bit' ); 
654       if ($res) { 
655                     info( t('Registration successful. Email send to user').EOL ); 
656       } 
657   }
658         
659         if (x($_POST,'page_users_block')){
660                 foreach($users as $uid){
661                         q("UPDATE `user` SET `blocked`=1-`blocked` WHERE `uid`=%s",
662                                 intval( $uid )
663                         );
664                 }
665                 notice( sprintf( tt("%s user blocked/unblocked", "%s users blocked/unblocked", count($users)), count($users)) );
666         }
667         if (x($_POST,'page_users_delete')){
668                 require_once("include/Contact.php");
669                 foreach($users as $uid){
670                         user_remove($uid);
671                 }
672                 notice( sprintf( tt("%s user deleted", "%s users deleted", count($users)), count($users)) );
673         }
674         
675         if (x($_POST,'page_users_approve')){
676                 require_once("mod/regmod.php");
677                 foreach($pending as $hash){
678                         user_allow($hash);
679                 }
680         }
681         if (x($_POST,'page_users_deny')){
682                 require_once("mod/regmod.php");
683                 foreach($pending as $hash){
684                         user_deny($hash);
685                 }
686         }
687         goaway($a->get_baseurl(true) . '/admin/users' );
688         return; // NOTREACHED   
689 }
690
691 /**
692  * @param App $a
693  * @return string
694  */
695 function admin_page_users(&$a){
696         if ($a->argc>2) {
697                 $uid = $a->argv[3];
698                 $user = q("SELECT * FROM `user` WHERE `uid`=%d", intval($uid));
699                 if (count($user)==0){
700                         notice( 'User not found' . EOL);
701                         goaway($a->get_baseurl(true) . '/admin/users' );
702                         return ''; // NOTREACHED
703                 }               
704                 switch($a->argv[2]){
705                         case "delete":{
706                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
707                                 // delete user
708                                 require_once("include/Contact.php");
709                                 user_remove($uid);
710                                 
711                                 notice( sprintf(t("User '%s' deleted"), $user[0]['username']) . EOL);
712                         }; break;
713                         case "block":{
714                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
715                                 q("UPDATE `user` SET `blocked`=%d WHERE `uid`=%s",
716                                         intval( 1-$user[0]['blocked'] ),
717                                         intval( $uid )
718                                 );
719                                 notice( sprintf( ($user[0]['blocked']?t("User '%s' unblocked"):t("User '%s' blocked")) , $user[0]['username']) . EOL);
720                         }; break;
721                 }
722                 goaway($a->get_baseurl(true) . '/admin/users' );
723                 return ''; // NOTREACHED
724                 
725         }
726         
727         /* get pending */
728         $pending = q("SELECT `register`.*, `contact`.`name`, `user`.`email`
729                                  FROM `register`
730                                  LEFT JOIN `contact` ON `register`.`uid` = `contact`.`uid`
731                                  LEFT JOIN `user` ON `register`.`uid` = `user`.`uid`;");
732         
733         
734         /* get users */
735
736         $total = q("SELECT count(*) as total FROM `user` where 1");
737         if(count($total)) {
738                 $a->set_pager_total($total[0]['total']);
739                 $a->set_pager_itemspage(100);
740         }
741         
742         
743         $users = q("SELECT `user` . * , `contact`.`name` , `contact`.`url` , `contact`.`micro`, `lastitem`.`lastitem_date`, `user`.`account_expired`
744                                 FROM
745                                         (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid`
746                                         FROM `item`
747                                         WHERE `item`.`type` = 'wall'
748                                         GROUP BY `item`.`uid`) AS `lastitem`
749                                                  RIGHT OUTER JOIN `user` ON `user`.`uid` = `lastitem`.`uid`,
750                                            `contact`
751                                 WHERE
752                                            `user`.`uid` = `contact`.`uid`
753                                                 AND `user`.`verified` =1
754                                         AND `contact`.`self` =1
755                                 ORDER BY `contact`.`name` LIMIT %d, %d
756                                 ",
757                                 intval($a->pager['start']),
758                                 intval($a->pager['itemspage'])
759                                 );
760                                         
761         function _setup_users($e){
762         $a = get_app();
763                 $accounts = Array(
764                         t('Normal Account'), 
765                         t('Soapbox Account'),
766                         t('Community/Celebrity Account'),
767                         t('Automatic Friend Account')
768                 );
769                 $e['page-flags'] = $accounts[$e['page-flags']];
770                 $e['register_date'] = relative_date($e['register_date']);
771                 $e['login_date'] = relative_date($e['login_date']);
772                 $e['lastitem_date'] = relative_date($e['lastitem_date']);
773         $e['is_admin'] = ($e['email'] === $a->config['admin_email']);
774         $e['deleted'] = ($e['account_removed']?relative_date($e['account_expires_on']):False);
775                 return $e;
776         }
777         $users = array_map("_setup_users", $users);
778         
779         
780         // Get rid of dashes in key names, Smarty3 can't handle them
781         // and extracting deleted users
782         
783         $tmp_users = Array();
784         $deleted = Array();
785         
786         while(count($users)) {
787                 $new_user = Array();
788                 foreach( array_pop($users) as $k => $v) {
789                         $k = str_replace('-','_',$k);
790                         $new_user[$k] = $v;
791                 }
792                 if($new_user['deleted']) {
793                         array_push($deleted, $new_user);
794                 }
795                 else {
796                         array_push($tmp_users, $new_user);
797                 }
798         }
799         //Reversing the two array, and moving $tmp_users to $users
800         array_reverse($deleted);
801         while(count($tmp_users)) {
802                 array_push($users, array_pop($tmp_users));
803         }
804
805         $t = get_markup_template("admin_users.tpl");
806         $o = replace_macros($t, array(
807                 // strings //
808                 '$title' => t('Administration'),
809                 '$page' => t('Users'),
810                 '$submit' => t('Submit'),
811                 '$select_all' => t('select all'),
812                 '$h_pending' => t('User registrations waiting for confirm'),
813                 '$h_deleted' => t('User waiting for permanent deletion'),
814                 '$th_pending' => array( t('Request date'), t('Name'), t('Email') ),
815                 '$no_pending' =>  t('No registrations.'),
816                 '$approve' => t('Approve'),
817                 '$deny' => t('Deny'),
818                 '$delete' => t('Delete'),
819                 '$block' => t('Block'),
820                 '$unblock' => t('Unblock'),
821         '$siteadmin' => t('Site admin'),
822         '$accountexpired' => t('Account expired'),
823                 
824                 '$h_users' => t('Users'),
825                 '$h_newuser' => t('New User'),
826                 '$th_deleted' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'), t('Deleted since') ),
827                 '$th_users' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'),  t('Account') ),
828
829                 '$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?'),
830                 '$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?'),
831
832         '$form_security_token' => get_form_security_token("admin_users"),
833
834                 // values //
835                 '$baseurl' => $a->get_baseurl(true),
836
837                 '$pending' => $pending,
838                 'deleted' => $deleted,
839                 '$users' => $users,
840                 '$newusername'  => array('new_user_name', t("Name"), '', t("Name of the new user.")), 
841     '$newusernickname'  => array('new_user_nickname', t("Nickname"), '', t("Nickname of the new user.")), 
842     '$newuseremail'  => array('new_user_email', t("Email"), '', t("Email address of the new user.")),
843         ));
844         $o .= paginate($a);
845         return $o;
846 }
847
848
849 /**
850  * Plugins admin page
851  *
852  * @param App $a
853  * @return string
854  */
855 function admin_page_plugins(&$a){
856
857         /**
858          * Single plugin
859          */
860         if ($a->argc == 3){
861                 $plugin = $a->argv[2];
862                 if (!is_file("addon/$plugin/$plugin.php")){
863                         notice( t("Item not found.") );
864                         return '';
865                 }
866
867                 if (x($_GET,"a") && $_GET['a']=="t"){
868                         check_form_security_token_redirectOnErr('/admin/plugins', 'admin_themes', 't');
869
870                         // Toggle plugin status
871                         $idx = array_search($plugin, $a->plugins);
872                         if ($idx !== false){
873                                 unset($a->plugins[$idx]);
874                                 uninstall_plugin($plugin);
875                                 info( sprintf( t("Plugin %s disabled."), $plugin ) );
876                         } else {
877                                 $a->plugins[] = $plugin;
878                                 install_plugin($plugin);
879                                 info( sprintf( t("Plugin %s enabled."), $plugin ) );
880                         }
881                         set_config("system","addon", implode(", ",$a->plugins));
882                         goaway($a->get_baseurl(true) . '/admin/plugins' );
883                         return ''; // NOTREACHED
884                 }
885                 // display plugin details
886                 require_once('library/markdown.php');
887
888                 if (in_array($plugin, $a->plugins)){
889                         $status="on"; $action= t("Disable");
890                 } else {
891                         $status="off"; $action= t("Enable");
892                 }
893
894                 $readme=Null;
895                 if (is_file("addon/$plugin/README.md")){
896                         $readme = file_get_contents("addon/$plugin/README.md");
897                         $readme = Markdown($readme);
898                 } else if (is_file("addon/$plugin/README")){
899                         $readme = "<pre>". file_get_contents("addon/$plugin/README") ."</pre>";
900                 }
901
902                 $admin_form="";
903                 if (is_array($a->plugins_admin) && in_array($plugin, $a->plugins_admin)){
904                         @require_once("addon/$plugin/$plugin.php");
905                         $func = $plugin.'_plugin_admin';
906                         $func($a, $admin_form);
907                 }
908
909                 $t = get_markup_template("admin_plugins_details.tpl");
910
911                 return replace_macros($t, array(
912                         '$title' => t('Administration'),
913                         '$page' => t('Plugins'),
914                         '$toggle' => t('Toggle'),
915                         '$settings' => t('Settings'),
916                         '$baseurl' => $a->get_baseurl(true),
917
918                         '$plugin' => $plugin,
919                         '$status' => $status,
920                         '$action' => $action,
921                         '$info' => get_plugin_info($plugin),
922                         '$str_author' => t('Author: '),
923                         '$str_maintainer' => t('Maintainer: '),
924
925                         '$admin_form' => $admin_form,
926                         '$function' => 'plugins',
927                         '$screenshot' => '',
928                         '$readme' => $readme,
929
930                         '$form_security_token' => get_form_security_token("admin_themes"),
931                 ));
932         }
933
934
935
936         /**
937          * List plugins
938          */
939
940         $plugins = array();
941         $files = glob("addon/*/");
942         if($files) {
943                 foreach($files as $file) {      
944                         if (is_dir($file)){
945                                 list($tmp, $id)=array_map("trim", explode("/",$file));
946                                 $info = get_plugin_info($id);
947                                 $plugins[] = array( $id, (in_array($id,  $a->plugins)?"on":"off") , $info);
948                         }
949                 }
950         }
951
952         $t = get_markup_template("admin_plugins.tpl");
953         return replace_macros($t, array(
954                 '$title' => t('Administration'),
955                 '$page' => t('Plugins'),
956                 '$submit' => t('Submit'),
957                 '$baseurl' => $a->get_baseurl(true),
958                 '$function' => 'plugins',       
959                 '$plugins' => $plugins,
960         '$form_security_token' => get_form_security_token("admin_themes"),
961         ));
962 }
963
964 /**
965  * @param array $themes
966  * @param string $th
967  * @param int $result
968  */
969 function toggle_theme(&$themes,$th,&$result) {
970         for($x = 0; $x < count($themes); $x ++) {
971                 if($themes[$x]['name'] === $th) {
972                         if($themes[$x]['allowed']) {
973                                 $themes[$x]['allowed'] = 0;
974                                 $result = 0;
975                         }
976                         else {
977                                 $themes[$x]['allowed'] = 1;
978                                 $result = 1;
979                         }
980                 }
981         }
982 }
983
984 /**
985  * @param array $themes
986  * @param string $th
987  * @return int
988  */
989 function theme_status($themes,$th) {
990         for($x = 0; $x < count($themes); $x ++) {
991                 if($themes[$x]['name'] === $th) {
992                         if($themes[$x]['allowed']) {
993                                 return 1;
994                         }
995                         else {
996                                 return 0;
997                         }
998                 }
999         }
1000         return 0;
1001 }
1002
1003
1004 /**
1005  * @param array $themes
1006  * @return string
1007  */
1008 function rebuild_theme_table($themes) {
1009         $o = '';
1010         if(count($themes)) {
1011                 foreach($themes as $th) {
1012                         if($th['allowed']) {
1013                                 if(strlen($o))
1014                                         $o .= ',';
1015                                 $o .= $th['name'];
1016                         }
1017                 }
1018         }
1019         return $o;
1020 }
1021
1022
1023 /**
1024  * Themes admin page
1025  *
1026  * @param App $a
1027  * @return string
1028  */
1029 function admin_page_themes(&$a){
1030
1031         $allowed_themes_str = get_config('system','allowed_themes');
1032         $allowed_themes_raw = explode(',',$allowed_themes_str);
1033         $allowed_themes = array();
1034         if(count($allowed_themes_raw))
1035                 foreach($allowed_themes_raw as $x)
1036                         if(strlen(trim($x)))
1037                                 $allowed_themes[] = trim($x);
1038
1039         $themes = array();
1040     $files = glob('view/theme/*');
1041     if($files) {
1042         foreach($files as $file) {
1043             $f = basename($file);
1044             $is_experimental = intval(file_exists($file . '/experimental'));
1045                         $is_supported = 1-(intval(file_exists($file . '/unsupported'))); // Is not used yet
1046                         $is_allowed = intval(in_array($f,$allowed_themes));
1047                         $themes[] = array('name' => $f, 'experimental' => $is_experimental, 'supported' => $is_supported, 'allowed' => $is_allowed);
1048         }
1049     }
1050
1051         if(! count($themes)) {
1052                 notice( t('No themes found.'));
1053                 return '';
1054         }
1055
1056         /**
1057          * Single theme
1058          */
1059
1060         if ($a->argc == 3){
1061                 $theme = $a->argv[2];
1062                 if(! is_dir("view/theme/$theme")){
1063                         notice( t("Item not found.") );
1064                         return '';
1065                 }
1066
1067                 if (x($_GET,"a") && $_GET['a']=="t"){
1068                         check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't');
1069
1070                         // Toggle theme status
1071
1072                         toggle_theme($themes,$theme,$result);
1073                         $s = rebuild_theme_table($themes);
1074                         if($result) {
1075                                 install_theme($theme);
1076                                 info( sprintf('Theme %s enabled.',$theme));
1077                         }
1078                         else {
1079                                 uninstall_theme($theme);
1080                                 info( sprintf('Theme %s disabled.',$theme));
1081                         }
1082
1083                         set_config('system','allowed_themes',$s);
1084                         goaway($a->get_baseurl(true) . '/admin/themes' );
1085                         return ''; // NOTREACHED
1086                 }
1087
1088                 // display theme details
1089                 require_once('library/markdown.php');
1090
1091                 if (theme_status($themes,$theme)) {
1092                         $status="on"; $action= t("Disable");
1093                 } else {
1094                         $status="off"; $action= t("Enable");
1095                 }
1096
1097                 $readme=Null;
1098                 if (is_file("view/theme/$theme/README.md")){
1099                         $readme = file_get_contents("view/theme/$theme/README.md");
1100                         $readme = Markdown($readme);
1101                 } else if (is_file("view/theme/$theme/README")){
1102                         $readme = "<pre>". file_get_contents("view/theme/$theme/README") ."</pre>";
1103                 }
1104
1105                 $admin_form="";
1106                 if (is_file("view/theme/$theme/config.php")){
1107                         require_once("view/theme/$theme/config.php");
1108                         if(function_exists("theme_admin")){
1109                                 $admin_form = theme_admin($a);
1110                         }
1111
1112                 }
1113
1114                 $screenshot = array( get_theme_screenshot($theme), t('Screenshot'));
1115                 if(! stristr($screenshot[0],$theme))
1116                         $screenshot = null;
1117
1118                 $t = get_markup_template("admin_plugins_details.tpl");
1119                 return replace_macros($t, array(
1120                         '$title' => t('Administration'),
1121                         '$page' => t('Themes'),
1122                         '$toggle' => t('Toggle'),
1123                         '$settings' => t('Settings'),
1124                         '$baseurl' => $a->get_baseurl(true),
1125
1126                         '$plugin' => $theme,
1127                         '$status' => $status,
1128                         '$action' => $action,
1129                         '$info' => get_theme_info($theme),
1130                         '$function' => 'themes',
1131                         '$admin_form' => $admin_form,
1132                         '$str_author' => t('Author: '),
1133                         '$str_maintainer' => t('Maintainer: '),
1134                         '$screenshot' => $screenshot,
1135                         '$readme' => $readme,
1136
1137                         '$form_security_token' => get_form_security_token("admin_themes"),
1138                 ));
1139         }
1140
1141         /**
1142          * List themes
1143          */
1144
1145         $xthemes = array();
1146         if($themes) {
1147                 foreach($themes as $th) {
1148                         $xthemes[] = array($th['name'],(($th['allowed']) ? "on" : "off"), get_theme_info($th['name']));
1149                 }
1150         }
1151
1152         $t = get_markup_template("admin_plugins.tpl");
1153         return replace_macros($t, array(
1154                 '$title' => t('Administration'),
1155                 '$page' => t('Themes'),
1156                 '$submit' => t('Submit'),
1157                 '$baseurl' => $a->get_baseurl(true),
1158                 '$function' => 'themes',
1159                 '$plugins' => $xthemes,
1160                 '$experimental' => t('[Experimental]'),
1161                 '$unsupported' => t('[Unsupported]'),
1162         '$form_security_token' => get_form_security_token("admin_themes"),
1163         ));
1164 }
1165
1166
1167 /**
1168  * Logs admin page
1169  *
1170  * @param App $a
1171  */
1172  
1173 function admin_page_logs_post(&$a) {
1174         if (x($_POST,"page_logs")) {
1175         check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
1176
1177                 $logfile                =       ((x($_POST,'logfile'))          ? notags(trim($_POST['logfile']))       : '');
1178                 $debugging              =       ((x($_POST,'debugging'))        ? true                                                          : false);
1179                 $loglevel               =       ((x($_POST,'loglevel'))         ? intval(trim($_POST['loglevel']))      : 0);
1180
1181                 set_config('system','logfile', $logfile);
1182                 set_config('system','debugging',  $debugging);
1183                 set_config('system','loglevel', $loglevel);
1184
1185                 
1186         }
1187
1188         info( t("Log settings updated.") );
1189         goaway($a->get_baseurl(true) . '/admin/logs' );
1190         return; // NOTREACHED   
1191 }
1192
1193 /**
1194  * @param App $a
1195  * @return string
1196  */
1197 function admin_page_logs(&$a){
1198         
1199         $log_choices = Array(
1200                 LOGGER_NORMAL => 'Normal',
1201                 LOGGER_TRACE => 'Trace',
1202                 LOGGER_DEBUG => 'Debug',
1203                 LOGGER_DATA => 'Data',
1204                 LOGGER_ALL => 'All'
1205         );
1206         
1207         $t = get_markup_template("admin_logs.tpl");
1208
1209         $f = get_config('system','logfile');
1210
1211         $data = '';
1212
1213         if(!file_exists($f)) {
1214                 $data = t("Error trying to open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f exist and is 
1215 readable.");
1216         }
1217         else {
1218                 $fp = fopen($f, 'r');
1219                 if(!$fp) {
1220                         $data = t("Couldn't open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f is readable.");
1221                 }
1222                 else {
1223                         $fstat = fstat($fp);
1224                         $size = $fstat['size'];
1225                         if($size != 0)
1226                         {
1227                                 if($size > 5000000 || $size < 0)
1228                                         $size = 5000000;
1229                                 $seek = fseek($fp,0-$size,SEEK_END);
1230                                 if($seek === 0) {
1231                                         $data = escape_tags(fread($fp,$size));
1232                                         while(! feof($fp))
1233                                                 $data .= escape_tags(fread($fp,4096));
1234                                 }
1235                         }
1236                         fclose($fp);
1237                 }
1238         }                       
1239
1240         return replace_macros($t, array(
1241                 '$title' => t('Administration'),
1242                 '$page' => t('Logs'),
1243                 '$submit' => t('Submit'),
1244                 '$clear' => t('Clear'),
1245                 '$data' => $data,
1246                 '$baseurl' => $a->get_baseurl(true),
1247                 '$logname' =>  get_config('system','logfile'),
1248                 
1249                                                                         // name, label, value, help string, extra data...
1250                 '$debugging'            => array('debugging', t("Enable Debugging"),get_config('system','debugging'), ""),
1251                 '$logfile'                      => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Friendica top-level directory.")),
1252                 '$loglevel'             => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices),
1253
1254         '$form_security_token' => get_form_security_token("admin_logs"),
1255         ));
1256 }
1257
1258 /**
1259  * @param App $a
1260  */
1261 function admin_page_remoteupdate_post(&$a) {
1262         // this function should be called via ajax post
1263         if(!is_site_admin()) {
1264                 return;
1265         }
1266
1267         
1268         if (x($_POST,'remotefile') && $_POST['remotefile']!=""){
1269                 $remotefile = $_POST['remotefile'];
1270                 $ftpdata = (x($_POST['ftphost'])?$_POST:false);
1271                 doUpdate($remotefile, $ftpdata);
1272         } else {
1273                 echo "No remote file to download. Abort!";
1274         }
1275
1276         killme();
1277 }
1278
1279 /**
1280  * @param App $a
1281  * @return string
1282  */
1283 function admin_page_remoteupdate(&$a) {
1284         if(!is_site_admin()) {
1285                 return login(false);
1286         }
1287
1288         $canwrite = canWeWrite();
1289         $canftp = function_exists('ftp_connect');
1290         
1291         $needupdate = true;
1292         $u = checkUpdate();
1293         if (!is_array($u)){
1294                 $needupdate = false;
1295                 $u = array('','','');
1296         }
1297         
1298         $tpl = get_markup_template("admin_remoteupdate.tpl");
1299         return replace_macros($tpl, array(
1300                 '$baseurl' => $a->get_baseurl(true),
1301                 '$submit' => t("Update now"),
1302                 '$close' => t("Close"),
1303                 '$localversion' => FRIENDICA_VERSION,
1304                 '$remoteversion' => $u[1],
1305                 '$needupdate' => $needupdate,
1306                 '$canwrite' => $canwrite,
1307                 '$canftp'       => $canftp,
1308                 '$ftphost'      => array('ftphost', t("FTP Host"), '',''),
1309                 '$ftppath'      => array('ftppath', t("FTP Path"), '/',''),
1310                 '$ftpuser'      => array('ftpuser', t("FTP User"), '',''),
1311                 '$ftppwd'       => array('ftppwd', t("FTP Password"), '',''),
1312                 '$remotefile'=>array('remotefile','', $u['2'],''),
1313         ));
1314         
1315 }