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