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