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