6 require_once("include/remoteupdate.php");
12 function admin_post(&$a){
15 if(!is_site_admin()) {
19 // do not allow a page manager to access the admin panel at all.
21 if(x($_SESSION,'submanage') && intval($_SESSION['submanage']))
30 admin_page_site_post($a);
33 admin_page_users_post($a);
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';
44 goaway($a->get_baseurl(true) . '/admin/plugins/' . $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")){
55 info(t('Theme settings updated.'));
58 goaway($a->get_baseurl(true) . '/admin/themes/' . $theme );
62 admin_page_logs_post($a);
65 admin_page_dbsync_post($a);
68 admin_page_remoteupdate_post($a);
73 goaway($a->get_baseurl(true) . '/admin' );
81 function admin_content(&$a) {
83 if(!is_site_admin()) {
87 if(x($_SESSION,'submanage') && intval($_SESSION['submanage']))
94 // array( url, name, extra css classes )
96 'site' => Array($a->get_baseurl(true)."/admin/site/", t("Site") , "site"),
97 'users' => Array($a->get_baseurl(true)."/admin/users/", t("Users") , "users"),
98 'plugins'=> Array($a->get_baseurl(true)."/admin/plugins/", t("Plugins") , "plugins"),
99 'themes' => Array($a->get_baseurl(true)."/admin/themes/", t("Themes") , "themes"),
100 'dbsync' => Array($a->get_baseurl(true)."/admin/dbsync/", t('DB updates'), "dbsync"),
101 //'update' => Array($a->get_baseurl(true)."/admin/update/", t("Software Update") , "update")
104 /* get plugins admin page */
106 $r = q("SELECT * FROM `addon` WHERE `plugin_admin`=1");
107 $aside['plugins_admin']=Array();
110 $aside['plugins_admin'][] = Array($a->get_baseurl(true)."/admin/plugins/".$plugin, $plugin, "plugin");
111 // temp plugins with admin
112 $a->plugins_admin[] = $plugin;
115 $aside['logs'] = Array($a->get_baseurl(true)."/admin/logs/", t("Logs"), "logs");
117 $t = get_markup_template("admin_aside.tpl");
118 $a->page['aside'] .= replace_macros( $t, array(
120 '$admtxt' => t('Admin'),
121 '$plugadmtxt' => t('Plugin Features'),
122 '$logtxt' => t('Logs'),
123 '$h_pending' => t('User registrations waiting for confirmation'),
124 '$admurl'=> $a->get_baseurl(true)."/admin/"
135 switch ($a->argv[1]){
137 $o = admin_page_site($a);
140 $o = admin_page_users($a);
143 $o = admin_page_plugins($a);
146 $o = admin_page_themes($a);
149 $o = admin_page_logs($a);
152 $o = admin_page_dbsync($a);
155 $o = admin_page_remoteupdate($a);
158 notice( t("Item not found.") );
161 $o = admin_page_summary($a);
179 function admin_page_summary(&$a) {
180 $r = q("SELECT `page-flags`, COUNT(uid) as `count` FROM `user` GROUP BY `page-flags`");
182 Array( t('Normal Account'), 0),
183 Array( t('Soapbox Account'), 0),
184 Array( t('Community/Celebrity Account'), 0),
185 Array( t('Automatic Friend Account'), 0),
186 Array( t('Blog Account'), 0),
187 Array( t('Private Forum'), 0)
191 foreach ($r as $u){ $accounts[$u['page-flags']][1] = $u['count']; $users+= $u['count']; }
193 logger('accounts: ' . print_r($accounts,true),LOGGER_DATA);
195 $r = q("SELECT COUNT(id) as `count` FROM `register`");
196 $pending = $r[0]['count'];
198 $r = q("select count(*) as total from deliverq where 1");
199 $deliverq = (($r) ? $r[0]['total'] : 0);
201 $r = q("select count(*) as total from queue where 1");
202 $queue = (($r) ? $r[0]['total'] : 0);
204 // We can do better, but this is a quick queue status
206 $queues = array( 'label' => t('Message queues'), 'deliverq' => $deliverq, 'queue' => $queue );
209 $t = get_markup_template("admin_summary.tpl");
210 return replace_macros($t, array(
211 '$title' => t('Administration'),
212 '$page' => t('Summary'),
213 '$queues' => $queues,
214 '$users' => Array( t('Registered users'), $users),
215 '$accounts' => $accounts,
216 '$pending' => Array( t('Pending registrations'), $pending),
217 '$version' => Array( t('Version'), FRIENDICA_VERSION),
218 '$build' => get_config('system','build'),
219 '$plugins' => Array( t('Active plugins'), $a->plugins )
228 function admin_page_site_post(&$a){
229 if (!x($_POST,"page_site")){
233 check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
235 $sitename = ((x($_POST,'sitename')) ? notags(trim($_POST['sitename'])) : '');
236 $banner = ((x($_POST,'banner')) ? trim($_POST['banner']) : false);
237 $language = ((x($_POST,'language')) ? notags(trim($_POST['language'])) : '');
238 $theme = ((x($_POST,'theme')) ? notags(trim($_POST['theme'])) : '');
239 $theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : '');
240 $maximagesize = ((x($_POST,'maximagesize')) ? intval(trim($_POST['maximagesize'])) : 0);
241 $maximagelength = ((x($_POST,'maximagelength')) ? intval(trim($_POST['maximagelength'])) : MAX_IMAGE_LENGTH);
242 $jpegimagequality = ((x($_POST,'jpegimagequality')) ? intval(trim($_POST['jpegimagequality'])) : JPEG_QUALITY);
245 $register_policy = ((x($_POST,'register_policy')) ? intval(trim($_POST['register_policy'])) : 0);
246 $daily_registrations = ((x($_POST,'max_daily_registrations')) ? intval(trim($_POST['max_daily_registrations'])) :0);
247 $abandon_days = ((x($_POST,'abandon_days')) ? intval(trim($_POST['abandon_days'])) : 0);
249 $register_text = ((x($_POST,'register_text')) ? notags(trim($_POST['register_text'])) : '');
251 $allowed_sites = ((x($_POST,'allowed_sites')) ? notags(trim($_POST['allowed_sites'])) : '');
252 $allowed_email = ((x($_POST,'allowed_email')) ? notags(trim($_POST['allowed_email'])) : '');
253 $block_public = ((x($_POST,'block_public')) ? True : False);
254 $force_publish = ((x($_POST,'publish_all')) ? True : False);
255 $global_directory = ((x($_POST,'directory_submit_url')) ? notags(trim($_POST['directory_submit_url'])) : '');
256 $thread_allow = ((x($_POST,'thread_allow')) ? True : False);
257 $newuser_private = ((x($_POST,'newuser_private')) ? True : False);
258 $enotify_no_content = ((x($_POST,'enotify_no_content')) ? True : False);
259 $private_addons = ((x($_POST,'private_addons')) ? True : False);
260 $disable_embedded = ((x($_POST,'disable_embedded')) ? True : False);
262 $no_multi_reg = ((x($_POST,'no_multi_reg')) ? True : False);
263 $no_openid = !((x($_POST,'no_openid')) ? True : False);
264 $no_regfullname = !((x($_POST,'no_regfullname')) ? True : False);
265 $no_utf = !((x($_POST,'no_utf')) ? True : False);
266 $no_community_page = !((x($_POST,'no_community_page')) ? True : False);
268 $verifyssl = ((x($_POST,'verifyssl')) ? True : False);
269 $proxyuser = ((x($_POST,'proxyuser')) ? notags(trim($_POST['proxyuser'])) : '');
270 $proxy = ((x($_POST,'proxy')) ? notags(trim($_POST['proxy'])) : '');
271 $timeout = ((x($_POST,'timeout')) ? intval(trim($_POST['timeout'])) : 60);
272 $delivery_interval = ((x($_POST,'delivery_interval')) ? intval(trim($_POST['delivery_interval'])) : 0);
273 $poll_interval = ((x($_POST,'poll_interval')) ? intval(trim($_POST['poll_interval'])) : 0);
274 $maxloadavg = ((x($_POST,'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50);
275 $dfrn_only = ((x($_POST,'dfrn_only')) ? True : False);
276 $ostatus_disabled = !((x($_POST,'ostatus_disabled')) ? True : False);
277 $ostatus_poll_interval = ((x($_POST,'ostatus_poll_interval')) ? intval(trim($_POST['ostatus_poll_interval'])) : 0);
278 $diaspora_enabled = ((x($_POST,'diaspora_enabled')) ? True : False);
279 $ssl_policy = ((x($_POST,'ssl_policy')) ? intval($_POST['ssl_policy']) : 0);
280 $new_share = ((x($_POST,'new_share')) ? True : False);
281 $hide_help = ((x($_POST,'hide_help')) ? True : False);
282 $use_fulltext_engine = ((x($_POST,'use_fulltext_engine')) ? True : False);
283 $itemcache = ((x($_POST,'itemcache')) ? notags(trim($_POST['itemcache'])) : '');
284 $itemcache_duration = ((x($_POST,'itemcache_duration')) ? intval($_POST['itemcache_duration']) : 0);
285 $lockpath = ((x($_POST,'lockpath')) ? notags(trim($_POST['lockpath'])) : '');
286 $temppath = ((x($_POST,'temppath')) ? notags(trim($_POST['temppath'])) : '');
287 $basepath = ((x($_POST,'basepath')) ? notags(trim($_POST['basepath'])) : '');
288 $singleuser = ((x($_POST,'singleuser')) ? notags(trim($_POST['singleuser'])) : '');
289 if($ssl_policy != intval(get_config('system','ssl_policy'))) {
290 if($ssl_policy == SSL_POLICY_FULL) {
291 q("update `contact` set
292 `url` = replace(`url` , 'http:' , 'https:'),
293 `photo` = replace(`photo` , 'http:' , 'https:'),
294 `thumb` = replace(`thumb` , 'http:' , 'https:'),
295 `micro` = replace(`micro` , 'http:' , 'https:'),
296 `request` = replace(`request`, 'http:' , 'https:'),
297 `notify` = replace(`notify` , 'http:' , 'https:'),
298 `poll` = replace(`poll` , 'http:' , 'https:'),
299 `confirm` = replace(`confirm`, 'http:' , 'https:'),
300 `poco` = replace(`poco` , 'http:' , 'https:')
303 q("update `profile` set
304 `photo` = replace(`photo` , 'http:' , 'https:'),
305 `thumb` = replace(`thumb` , 'http:' , 'https:')
309 elseif($ssl_policy == SSL_POLICY_SELFSIGN) {
310 q("update `contact` set
311 `url` = replace(`url` , 'https:' , 'http:'),
312 `photo` = replace(`photo` , 'https:' , 'http:'),
313 `thumb` = replace(`thumb` , 'https:' , 'http:'),
314 `micro` = replace(`micro` , 'https:' , 'http:'),
315 `request` = replace(`request`, 'https:' , 'http:'),
316 `notify` = replace(`notify` , 'https:' , 'http:'),
317 `poll` = replace(`poll` , 'https:' , 'http:'),
318 `confirm` = replace(`confirm`, 'https:' , 'http:'),
319 `poco` = replace(`poco` , 'https:' , 'http:')
322 q("update `profile` set
323 `photo` = replace(`photo` , 'https:' , 'http:'),
324 `thumb` = replace(`thumb` , 'https:' , 'http:')
329 set_config('system','ssl_policy',$ssl_policy);
330 set_config('system','delivery_interval',$delivery_interval);
331 set_config('system','poll_interval',$poll_interval);
332 set_config('system','maxloadavg',$maxloadavg);
333 set_config('config','sitename',$sitename);
335 // don't know why, but del_config doesn't work...
336 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
341 set_config('system','banner', $banner);
343 set_config('system','language', $language);
344 set_config('system','theme', $theme);
345 if ( $theme_mobile === '---' ) {
346 del_config('system','mobile-theme');
348 set_config('system','mobile-theme', $theme_mobile);
350 if ( $singleuser === '---' ) {
351 del_config('system','singleuser');
353 set_config('system','singleuser', $singleuser);
355 set_config('system','maximagesize', $maximagesize);
356 set_config('system','max_image_length', $maximagelength);
357 set_config('system','jpeg_quality', $jpegimagequality);
359 set_config('config','register_policy', $register_policy);
360 set_config('system','max_daily_registrations', $daily_registrations);
361 set_config('system','account_abandon_days', $abandon_days);
362 set_config('config','register_text', $register_text);
363 set_config('system','allowed_sites', $allowed_sites);
364 set_config('system','allowed_email', $allowed_email);
365 set_config('system','block_public', $block_public);
366 set_config('system','publish_all', $force_publish);
367 if ($global_directory==""){
368 // don't know why, but del_config doesn't work...
369 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
371 dbesc("directory_submit_url")
374 set_config('system','directory_submit_url', $global_directory);
376 set_config('system','thread_allow', $thread_allow);
377 set_config('system','newuser_private', $newuser_private);
378 set_config('system','enotify_no_content', $enotify_no_content);
379 set_config('system','disable_embedded', $disable_embedded);
381 set_config('system','block_extended_register', $no_multi_reg);
382 set_config('system','no_openid', $no_openid);
383 set_config('system','no_regfullname', $no_regfullname);
384 set_config('system','no_community_page', $no_community_page);
385 set_config('system','no_utf', $no_utf);
386 set_config('system','verifyssl', $verifyssl);
387 set_config('system','proxyuser', $proxyuser);
388 set_config('system','proxy', $proxy);
389 set_config('system','curl_timeout', $timeout);
390 set_config('system','dfrn_only', $dfrn_only);
391 set_config('system','ostatus_disabled', $ostatus_disabled);
392 set_config('system','ostatus_poll_interval', $ostatus_poll_interval);
393 set_config('system','diaspora_enabled', $diaspora_enabled);
394 set_config('config','private_addons', $private_addons);
396 set_config('system','new_share', $new_share);
397 set_config('system','hide_help', $hide_help);
398 set_config('system','use_fulltext_engine', $use_fulltext_engine);
399 set_config('system','itemcache', $itemcache);
400 set_config('system','itemcache_duration', $itemcache_duration);
401 set_config('system','lockpath', $lockpath);
402 set_config('system','temppath', $temppath);
403 set_config('system','basepath', $basepath);
405 info( t('Site settings updated.') . EOL);
406 goaway($a->get_baseurl(true) . '/admin/site' );
407 return; // NOTREACHED
415 function admin_page_site(&$a) {
417 /* Installed langs */
418 $lang_choices = array();
419 $langs = glob('view/*/strings.php');
421 if(is_array($langs) && count($langs)) {
422 if(! in_array('view/en/strings.php',$langs))
423 $langs[] = 'view/en/';
425 foreach($langs as $l) {
426 $t = explode("/",$l);
427 $lang_choices[$t[1]] = $t[1];
431 /* Installed themes */
432 $theme_choices = array();
433 $theme_choices_mobile = array();
434 $theme_choices_mobile["---"] = t("No special theme for mobile devices");
435 $files = glob('view/theme/*');
437 foreach($files as $file) {
438 $f = basename($file);
439 $theme_name = ((file_exists($file . '/experimental')) ? sprintf("%s - \x28Experimental\x29", $f) : $f);
440 if (file_exists($file . '/mobile')) {
441 $theme_choices_mobile[$f] = $theme_name;
444 $theme_choices[$f] = $theme_name;
449 /* OStatus conversation poll choices */
450 $ostatus_poll_choices = array(
452 "0" => t("Frequently"),
454 "720" => t("Twice daily"),
458 /* get user names to make the install a personal install of X */
459 $user_names = array();
460 $user_names['---'] = t('Multi user instance');
461 $users = q("SELECT username, nickname FROM `user`");
462 foreach ($users as $user) {
463 $user_names[$user['nickname']] = $user['username'];
467 $banner = get_config('system','banner');
469 $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>';
470 $banner = htmlspecialchars($banner);
472 //echo "<pre>"; var_dump($lang_choices); die("</pre>");
474 /* Register policy */
475 $register_choices = Array(
476 REGISTER_CLOSED => t("Closed"),
477 REGISTER_APPROVE => t("Requires approval"),
478 REGISTER_OPEN => t("Open")
481 $ssl_choices = array(
482 SSL_POLICY_NONE => t("No SSL policy, links will track page SSL state"),
483 SSL_POLICY_FULL => t("Force all links to use SSL"),
484 SSL_POLICY_SELFSIGN => t("Self-signed certificate, use SSL for local links only (discouraged)")
487 $t = get_markup_template("admin_site.tpl");
488 return replace_macros($t, array(
489 '$title' => t('Administration'),
490 '$page' => t('Site'),
491 '$submit' => t('Submit'),
492 '$registration' => t('Registration'),
493 '$upload' => t('File upload'),
494 '$corporate' => t('Policies'),
495 '$advanced' => t('Advanced'),
496 '$performance' => t('Performance'),
498 '$baseurl' => $a->get_baseurl(true),
499 // name, label, value, help string, extra data...
500 '$sitename' => array('sitename', t("Site name"), htmlentities($a->config['sitename'], ENT_QUOTES), 'UTF-8'),
501 '$banner' => array('banner', t("Banner/Logo"), $banner, ""),
502 '$language' => array('language', t("System language"), get_config('system','language'), "", $lang_choices),
503 '$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),
504 '$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile-theme'), t("Theme for mobile devices"), $theme_choices_mobile),
505 '$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),
506 '$new_share' => array('new_share', t("'Share' element"), get_config('system','new_share'), t("Activates the bbcode element 'share' for repeating items.")),
507 '$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.")),
508 '$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),
509 '$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.")),
510 '$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.")),
511 '$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.")),
513 '$register_policy' => array('register_policy', t("Register policy"), $a->config['register_policy'], "", $register_choices),
514 '$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.")),
515 '$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.")),
516 '$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.')),
517 '$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")),
518 '$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")),
519 '$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.")),
520 '$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.")),
521 '$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.")),
522 '$thread_allow' => array('thread_allow', t("Allow threaded items"), get_config('system','thread_allow'), t("Allow infinite level threading for items on this site.")),
523 '$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.")),
524 '$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.")),
525 '$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.")),
526 '$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.")),
528 '$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.")),
529 '$no_openid' => array('no_openid', t("OpenID support"), !get_config('system','no_openid'), t("OpenID support for registration and logins.")),
530 '$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")),
531 '$no_utf' => array('no_utf', t("UTF-8 Regular expressions"), !get_config('system','no_utf'), t("Use PHP UTF8 regular expressions")),
532 '$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.")),
533 '$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.")),
534 '$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),
535 '$diaspora_enabled' => array('diaspora_enabled', t("Enable Diaspora support"), get_config('system','diaspora_enabled'), t("Provide built-in Diaspora network compatibility.")),
536 '$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.")),
537 '$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.")),
538 '$proxyuser' => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""),
539 '$proxy' => array('proxy', t("Proxy URL"), get_config('system','proxy'), ""),
540 '$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).")),
541 '$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.")),
542 '$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.")),
543 '$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.")),
545 '$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.")),
546 '$itemcache' => array('itemcache', t("Path to item cache"), get_config('system','itemcache'), "The item caches buffers generated bbcode and external images."),
547 '$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).")),
548 '$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."),
549 '$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."),
550 '$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."),
551 '$form_security_token' => get_form_security_token("admin_site"),
558 function admin_page_dbsync(&$a) {
562 if($a->argc > 3 && intval($a->argv[3]) && $a->argv[2] === 'mark') {
563 set_config('database', 'update_' . intval($a->argv[3]), 'success');
564 $curr = get_config('system','build');
565 if(intval($curr) == intval($a->argv[3]))
566 set_config('system','build',intval($curr) + 1);
567 info( t('Update has been marked successful') . EOL);
568 goaway($a->get_baseurl(true) . '/admin/dbsync');
571 if($a->argc > 2 && intval($a->argv[2])) {
572 require_once('update.php');
573 $func = 'update_' . intval($a->argv[2]);
574 if(function_exists($func)) {
576 if($retval === UPDATE_FAILED) {
577 $o .= sprintf( t('Executing %s failed. Check system logs.'), $func);
579 elseif($retval === UPDATE_SUCCESS) {
580 $o .= sprintf( t('Update %s was successfully applied.', $func));
581 set_config('database',$func, 'success');
584 $o .= sprintf( t('Update %s did not return a status. Unknown if it succeeded.'), $func);
587 $o .= sprintf( t('Update function %s could not be found.'), $func);
592 $r = q("select * from config where `cat` = 'database' ");
595 $upd = intval(substr($rr['k'],7));
596 if($upd < 1139 || $rr['v'] === 'success')
602 return '<h3>' . t('No failed updates.') . '</h3>';
604 $o = replace_macros(get_markup_template('failed_updates.tpl'),array(
605 '$base' => $a->get_baseurl(true),
606 '$banner' => t('Failed Updates'),
607 '$desc' => t('This does not include updates prior to 1139, which did not return a status.'),
608 '$mark' => t('Mark success (if update was manually applied)'),
609 '$apply' => t('Attempt to execute this update step automatically'),
622 function admin_page_users_post(&$a){
623 $pending = ( x($_POST, 'pending') ? $_POST['pending'] : Array() );
624 $users = ( x($_POST, 'user') ? $_POST['user'] : Array() );
626 check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
628 if (x($_POST,'page_users_block')){
629 foreach($users as $uid){
630 q("UPDATE `user` SET `blocked`=1-`blocked` WHERE `uid`=%s",
634 notice( sprintf( tt("%s user blocked/unblocked", "%s users blocked/unblocked", count($users)), count($users)) );
636 if (x($_POST,'page_users_delete')){
637 require_once("include/Contact.php");
638 foreach($users as $uid){
641 notice( sprintf( tt("%s user deleted", "%s users deleted", count($users)), count($users)) );
644 if (x($_POST,'page_users_approve')){
645 require_once("mod/regmod.php");
646 foreach($pending as $hash){
650 if (x($_POST,'page_users_deny')){
651 require_once("mod/regmod.php");
652 foreach($pending as $hash){
656 goaway($a->get_baseurl(true) . '/admin/users' );
657 return; // NOTREACHED
664 function admin_page_users(&$a){
667 $user = q("SELECT * FROM `user` WHERE `uid`=%d", intval($uid));
668 if (count($user)==0){
669 notice( 'User not found' . EOL);
670 goaway($a->get_baseurl(true) . '/admin/users' );
671 return ''; // NOTREACHED
675 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
677 require_once("include/Contact.php");
680 notice( sprintf(t("User '%s' deleted"), $user[0]['username']) . EOL);
683 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
684 q("UPDATE `user` SET `blocked`=%d WHERE `uid`=%s",
685 intval( 1-$user[0]['blocked'] ),
688 notice( sprintf( ($user[0]['blocked']?t("User '%s' unblocked"):t("User '%s' blocked")) , $user[0]['username']) . EOL);
691 goaway($a->get_baseurl(true) . '/admin/users' );
692 return ''; // NOTREACHED
697 $pending = q("SELECT `register`.*, `contact`.`name`, `user`.`email`
699 LEFT JOIN `contact` ON `register`.`uid` = `contact`.`uid`
700 LEFT JOIN `user` ON `register`.`uid` = `user`.`uid`;");
705 $total = q("SELECT count(*) as total FROM `user` where 1");
707 $a->set_pager_total($total[0]['total']);
708 $a->set_pager_itemspage(100);
712 $users = q("SELECT `user` . * , `contact`.`name` , `contact`.`url` , `contact`.`micro`, `lastitem`.`lastitem_date`, `user`.`account_expired`
714 (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid`
716 WHERE `item`.`type` = 'wall'
717 GROUP BY `item`.`uid`) AS `lastitem`
718 RIGHT OUTER JOIN `user` ON `user`.`uid` = `lastitem`.`uid`,
721 `user`.`uid` = `contact`.`uid`
722 AND `user`.`verified` =1
723 AND `contact`.`self` =1
724 ORDER BY `contact`.`name` LIMIT %d, %d
726 intval($a->pager['start']),
727 intval($a->pager['itemspage'])
730 function _setup_users($e){
734 t('Soapbox Account'),
735 t('Community/Celebrity Account'),
736 t('Automatic Friend Account')
738 $e['page-flags'] = $accounts[$e['page-flags']];
739 $e['register_date'] = relative_date($e['register_date']);
740 $e['login_date'] = relative_date($e['login_date']);
741 $e['lastitem_date'] = relative_date($e['lastitem_date']);
742 $e['is_admin'] = ($e['email'] === $a->config['admin_email']);
745 $users = array_map("_setup_users", $users);
748 // Get rid of dashes in key names, Smarty3 can't handle them
749 foreach($users as $key => $user) {
751 foreach($user as $k => $v) {
752 $k = str_replace('-','_',$k);
755 $users[$key] = $new_user;
758 $t = get_markup_template("admin_users.tpl");
759 $o = replace_macros($t, array(
761 '$title' => t('Administration'),
762 '$page' => t('Users'),
763 '$submit' => t('Submit'),
764 '$select_all' => t('select all'),
765 '$h_pending' => t('User registrations waiting for confirm'),
766 '$th_pending' => array( t('Request date'), t('Name'), t('Email') ),
767 '$no_pending' => t('No registrations.'),
768 '$approve' => t('Approve'),
769 '$deny' => t('Deny'),
770 '$delete' => t('Delete'),
771 '$block' => t('Block'),
772 '$unblock' => t('Unblock'),
773 '$siteadmin' => t('Site admin'),
774 '$accountexpired' => t('Account expired'),
776 '$h_users' => t('Users'),
777 '$th_users' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'), t('Account') ),
779 '$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?'),
780 '$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?'),
782 '$form_security_token' => get_form_security_token("admin_users"),
785 '$baseurl' => $a->get_baseurl(true),
787 '$pending' => $pending,
801 function admin_page_plugins(&$a){
807 $plugin = $a->argv[2];
808 if (!is_file("addon/$plugin/$plugin.php")){
809 notice( t("Item not found.") );
813 if (x($_GET,"a") && $_GET['a']=="t"){
814 check_form_security_token_redirectOnErr('/admin/plugins', 'admin_themes', 't');
816 // Toggle plugin status
817 $idx = array_search($plugin, $a->plugins);
819 unset($a->plugins[$idx]);
820 uninstall_plugin($plugin);
821 info( sprintf( t("Plugin %s disabled."), $plugin ) );
823 $a->plugins[] = $plugin;
824 install_plugin($plugin);
825 info( sprintf( t("Plugin %s enabled."), $plugin ) );
827 set_config("system","addon", implode(", ",$a->plugins));
828 goaway($a->get_baseurl(true) . '/admin/plugins' );
829 return ''; // NOTREACHED
831 // display plugin details
832 require_once('library/markdown.php');
834 if (in_array($plugin, $a->plugins)){
835 $status="on"; $action= t("Disable");
837 $status="off"; $action= t("Enable");
841 if (is_file("addon/$plugin/README.md")){
842 $readme = file_get_contents("addon/$plugin/README.md");
843 $readme = Markdown($readme);
844 } else if (is_file("addon/$plugin/README")){
845 $readme = "<pre>". file_get_contents("addon/$plugin/README") ."</pre>";
849 if (is_array($a->plugins_admin) && in_array($plugin, $a->plugins_admin)){
850 @require_once("addon/$plugin/$plugin.php");
851 $func = $plugin.'_plugin_admin';
852 $func($a, $admin_form);
855 $t = get_markup_template("admin_plugins_details.tpl");
857 return replace_macros($t, array(
858 '$title' => t('Administration'),
859 '$page' => t('Plugins'),
860 '$toggle' => t('Toggle'),
861 '$settings' => t('Settings'),
862 '$baseurl' => $a->get_baseurl(true),
864 '$plugin' => $plugin,
865 '$status' => $status,
866 '$action' => $action,
867 '$info' => get_plugin_info($plugin),
868 '$str_author' => t('Author: '),
869 '$str_maintainer' => t('Maintainer: '),
871 '$admin_form' => $admin_form,
872 '$function' => 'plugins',
874 '$readme' => $readme,
876 '$form_security_token' => get_form_security_token("admin_themes"),
887 $files = glob("addon/*/");
889 foreach($files as $file) {
891 list($tmp, $id)=array_map("trim", explode("/",$file));
892 $info = get_plugin_info($id);
893 $plugins[] = array( $id, (in_array($id, $a->plugins)?"on":"off") , $info);
898 $t = get_markup_template("admin_plugins.tpl");
899 return replace_macros($t, array(
900 '$title' => t('Administration'),
901 '$page' => t('Plugins'),
902 '$submit' => t('Submit'),
903 '$baseurl' => $a->get_baseurl(true),
904 '$function' => 'plugins',
905 '$plugins' => $plugins,
906 '$form_security_token' => get_form_security_token("admin_themes"),
911 * @param array $themes
915 function toggle_theme(&$themes,$th,&$result) {
916 for($x = 0; $x < count($themes); $x ++) {
917 if($themes[$x]['name'] === $th) {
918 if($themes[$x]['allowed']) {
919 $themes[$x]['allowed'] = 0;
923 $themes[$x]['allowed'] = 1;
931 * @param array $themes
935 function theme_status($themes,$th) {
936 for($x = 0; $x < count($themes); $x ++) {
937 if($themes[$x]['name'] === $th) {
938 if($themes[$x]['allowed']) {
951 * @param array $themes
954 function rebuild_theme_table($themes) {
957 foreach($themes as $th) {
975 function admin_page_themes(&$a){
977 $allowed_themes_str = get_config('system','allowed_themes');
978 $allowed_themes_raw = explode(',',$allowed_themes_str);
979 $allowed_themes = array();
980 if(count($allowed_themes_raw))
981 foreach($allowed_themes_raw as $x)
983 $allowed_themes[] = trim($x);
986 $files = glob('view/theme/*');
988 foreach($files as $file) {
989 $f = basename($file);
990 $is_experimental = intval(file_exists($file . '/experimental'));
991 $is_supported = 1-(intval(file_exists($file . '/unsupported'))); // Is not used yet
992 $is_allowed = intval(in_array($f,$allowed_themes));
993 $themes[] = array('name' => $f, 'experimental' => $is_experimental, 'supported' => $is_supported, 'allowed' => $is_allowed);
997 if(! count($themes)) {
998 notice( t('No themes found.'));
1007 $theme = $a->argv[2];
1008 if(! is_dir("view/theme/$theme")){
1009 notice( t("Item not found.") );
1013 if (x($_GET,"a") && $_GET['a']=="t"){
1014 check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't');
1016 // Toggle theme status
1018 toggle_theme($themes,$theme,$result);
1019 $s = rebuild_theme_table($themes);
1021 install_theme($theme);
1022 info( sprintf('Theme %s enabled.',$theme));
1025 uninstall_theme($theme);
1026 info( sprintf('Theme %s disabled.',$theme));
1029 set_config('system','allowed_themes',$s);
1030 goaway($a->get_baseurl(true) . '/admin/themes' );
1031 return ''; // NOTREACHED
1034 // display theme details
1035 require_once('library/markdown.php');
1037 if (theme_status($themes,$theme)) {
1038 $status="on"; $action= t("Disable");
1040 $status="off"; $action= t("Enable");
1044 if (is_file("view/theme/$theme/README.md")){
1045 $readme = file_get_contents("view/theme/$theme/README.md");
1046 $readme = Markdown($readme);
1047 } else if (is_file("view/theme/$theme/README")){
1048 $readme = "<pre>". file_get_contents("view/theme/$theme/README") ."</pre>";
1052 if (is_file("view/theme/$theme/config.php")){
1053 require_once("view/theme/$theme/config.php");
1054 if(function_exists("theme_admin")){
1055 $admin_form = theme_admin($a);
1060 $screenshot = array( get_theme_screenshot($theme), t('Screenshot'));
1061 if(! stristr($screenshot[0],$theme))
1064 $t = get_markup_template("admin_plugins_details.tpl");
1065 return replace_macros($t, array(
1066 '$title' => t('Administration'),
1067 '$page' => t('Themes'),
1068 '$toggle' => t('Toggle'),
1069 '$settings' => t('Settings'),
1070 '$baseurl' => $a->get_baseurl(true),
1072 '$plugin' => $theme,
1073 '$status' => $status,
1074 '$action' => $action,
1075 '$info' => get_theme_info($theme),
1076 '$function' => 'themes',
1077 '$admin_form' => $admin_form,
1078 '$str_author' => t('Author: '),
1079 '$str_maintainer' => t('Maintainer: '),
1080 '$screenshot' => $screenshot,
1081 '$readme' => $readme,
1083 '$form_security_token' => get_form_security_token("admin_themes"),
1093 foreach($themes as $th) {
1094 $xthemes[] = array($th['name'],(($th['allowed']) ? "on" : "off"), get_theme_info($th['name']));
1098 $t = get_markup_template("admin_plugins.tpl");
1099 return replace_macros($t, array(
1100 '$title' => t('Administration'),
1101 '$page' => t('Themes'),
1102 '$submit' => t('Submit'),
1103 '$baseurl' => $a->get_baseurl(true),
1104 '$function' => 'themes',
1105 '$plugins' => $xthemes,
1106 '$experimental' => t('[Experimental]'),
1107 '$unsupported' => t('[Unsupported]'),
1108 '$form_security_token' => get_form_security_token("admin_themes"),
1119 function admin_page_logs_post(&$a) {
1120 if (x($_POST,"page_logs")) {
1121 check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
1123 $logfile = ((x($_POST,'logfile')) ? notags(trim($_POST['logfile'])) : '');
1124 $debugging = ((x($_POST,'debugging')) ? true : false);
1125 $loglevel = ((x($_POST,'loglevel')) ? intval(trim($_POST['loglevel'])) : 0);
1127 set_config('system','logfile', $logfile);
1128 set_config('system','debugging', $debugging);
1129 set_config('system','loglevel', $loglevel);
1134 info( t("Log settings updated.") );
1135 goaway($a->get_baseurl(true) . '/admin/logs' );
1136 return; // NOTREACHED
1143 function admin_page_logs(&$a){
1145 $log_choices = Array(
1146 LOGGER_NORMAL => 'Normal',
1147 LOGGER_TRACE => 'Trace',
1148 LOGGER_DEBUG => 'Debug',
1149 LOGGER_DATA => 'Data',
1153 $t = get_markup_template("admin_logs.tpl");
1155 $f = get_config('system','logfile');
1159 if(!file_exists($f)) {
1160 $data = t("Error trying to open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f exist and is
1164 $fp = fopen($f, 'r');
1166 $data = t("Couldn't open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f is readable.");
1169 $fstat = fstat($fp);
1170 $size = $fstat['size'];
1173 if($size > 5000000 || $size < 0)
1175 $seek = fseek($fp,0-$size,SEEK_END);
1177 $data = escape_tags(fread($fp,$size));
1179 $data .= escape_tags(fread($fp,4096));
1186 return replace_macros($t, array(
1187 '$title' => t('Administration'),
1188 '$page' => t('Logs'),
1189 '$submit' => t('Submit'),
1190 '$clear' => t('Clear'),
1192 '$baseurl' => $a->get_baseurl(true),
1193 '$logname' => get_config('system','logfile'),
1195 // name, label, value, help string, extra data...
1196 '$debugging' => array('debugging', t("Enable Debugging"),get_config('system','debugging'), ""),
1197 '$logfile' => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Friendica top-level directory.")),
1198 '$loglevel' => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices),
1200 '$form_security_token' => get_form_security_token("admin_logs"),
1207 function admin_page_remoteupdate_post(&$a) {
1208 // this function should be called via ajax post
1209 if(!is_site_admin()) {
1214 if (x($_POST,'remotefile') && $_POST['remotefile']!=""){
1215 $remotefile = $_POST['remotefile'];
1216 $ftpdata = (x($_POST['ftphost'])?$_POST:false);
1217 doUpdate($remotefile, $ftpdata);
1219 echo "No remote file to download. Abort!";
1229 function admin_page_remoteupdate(&$a) {
1230 if(!is_site_admin()) {
1231 return login(false);
1234 $canwrite = canWeWrite();
1235 $canftp = function_exists('ftp_connect');
1240 $needupdate = false;
1241 $u = array('','','');
1244 $tpl = get_markup_template("admin_remoteupdate.tpl");
1245 return replace_macros($tpl, array(
1246 '$baseurl' => $a->get_baseurl(true),
1247 '$submit' => t("Update now"),
1248 '$close' => t("Close"),
1249 '$localversion' => FRIENDICA_VERSION,
1250 '$remoteversion' => $u[1],
1251 '$needupdate' => $needupdate,
1252 '$canwrite' => $canwrite,
1253 '$canftp' => $canftp,
1254 '$ftphost' => array('ftphost', t("FTP Host"), '',''),
1255 '$ftppath' => array('ftppath', t("FTP Path"), '/',''),
1256 '$ftpuser' => array('ftpuser', t("FTP User"), '',''),
1257 '$ftppwd' => array('ftppwd', t("FTP Password"), '',''),
1258 '$remotefile'=>array('remotefile','', $u['2'],''),