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