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