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 $diaspora_enabled = ((x($_POST,'diaspora_enabled')) ? True : False);
278 $ssl_policy = ((x($_POST,'ssl_policy')) ? intval($_POST['ssl_policy']) : 0);
279 $new_share = ((x($_POST,'new_share')) ? True : False);
280 $hide_help = ((x($_POST,'hide_help')) ? True : False);
281 $use_fulltext_engine = ((x($_POST,'use_fulltext_engine')) ? True : False);
282 $itemcache = ((x($_POST,'itemcache')) ? notags(trim($_POST['itemcache'])) : '');
283 $itemcache_duration = ((x($_POST,'itemcache_duration')) ? intval($_POST['itemcache_duration']) : 0);
284 $lockpath = ((x($_POST,'lockpath')) ? notags(trim($_POST['lockpath'])) : '');
285 $temppath = ((x($_POST,'temppath')) ? notags(trim($_POST['temppath'])) : '');
286 $basepath = ((x($_POST,'basepath')) ? notags(trim($_POST['basepath'])) : '');
287 $singleuser = ((x($_POST,'singleuser')) ? notags(trim($_POST['singleuser'])) : '');
288 if($ssl_policy != intval(get_config('system','ssl_policy'))) {
289 if($ssl_policy == SSL_POLICY_FULL) {
290 q("update `contact` set
291 `url` = replace(`url` , 'http:' , 'https:'),
292 `photo` = replace(`photo` , 'http:' , 'https:'),
293 `thumb` = replace(`thumb` , 'http:' , 'https:'),
294 `micro` = replace(`micro` , 'http:' , 'https:'),
295 `request` = replace(`request`, 'http:' , 'https:'),
296 `notify` = replace(`notify` , 'http:' , 'https:'),
297 `poll` = replace(`poll` , 'http:' , 'https:'),
298 `confirm` = replace(`confirm`, 'http:' , 'https:'),
299 `poco` = replace(`poco` , 'http:' , 'https:')
302 q("update `profile` set
303 `photo` = replace(`photo` , 'http:' , 'https:'),
304 `thumb` = replace(`thumb` , 'http:' , 'https:')
308 elseif($ssl_policy == SSL_POLICY_SELFSIGN) {
309 q("update `contact` set
310 `url` = replace(`url` , 'https:' , 'http:'),
311 `photo` = replace(`photo` , 'https:' , 'http:'),
312 `thumb` = replace(`thumb` , 'https:' , 'http:'),
313 `micro` = replace(`micro` , 'https:' , 'http:'),
314 `request` = replace(`request`, 'https:' , 'http:'),
315 `notify` = replace(`notify` , 'https:' , 'http:'),
316 `poll` = replace(`poll` , 'https:' , 'http:'),
317 `confirm` = replace(`confirm`, 'https:' , 'http:'),
318 `poco` = replace(`poco` , 'https:' , 'http:')
321 q("update `profile` set
322 `photo` = replace(`photo` , 'https:' , 'http:'),
323 `thumb` = replace(`thumb` , 'https:' , 'http:')
328 set_config('system','ssl_policy',$ssl_policy);
329 set_config('system','delivery_interval',$delivery_interval);
330 set_config('system','poll_interval',$poll_interval);
331 set_config('system','maxloadavg',$maxloadavg);
332 set_config('config','sitename',$sitename);
334 // don't know why, but del_config doesn't work...
335 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
340 set_config('system','banner', $banner);
342 set_config('system','language', $language);
343 set_config('system','theme', $theme);
344 if ( $theme_mobile === '---' ) {
345 del_config('system','mobile-theme');
347 set_config('system','mobile-theme', $theme_mobile);
349 if ( $singleuser === '---' ) {
350 del_config('system','singleuser');
352 set_config('system','singleuser', $singleuser);
354 set_config('system','maximagesize', $maximagesize);
355 set_config('system','max_image_length', $maximagelength);
356 set_config('system','jpeg_quality', $jpegimagequality);
358 set_config('config','register_policy', $register_policy);
359 set_config('system','max_daily_registrations', $daily_registrations);
360 set_config('system','account_abandon_days', $abandon_days);
361 set_config('config','register_text', $register_text);
362 set_config('system','allowed_sites', $allowed_sites);
363 set_config('system','allowed_email', $allowed_email);
364 set_config('system','block_public', $block_public);
365 set_config('system','publish_all', $force_publish);
366 if ($global_directory==""){
367 // don't know why, but del_config doesn't work...
368 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
370 dbesc("directory_submit_url")
373 set_config('system','directory_submit_url', $global_directory);
375 set_config('system','thread_allow', $thread_allow);
376 set_config('system','newuser_private', $newuser_private);
377 set_config('system','enotify_no_content', $enotify_no_content);
378 set_config('system','disable_embedded', $disable_embedded);
380 set_config('system','block_extended_register', $no_multi_reg);
381 set_config('system','no_openid', $no_openid);
382 set_config('system','no_regfullname', $no_regfullname);
383 set_config('system','no_community_page', $no_community_page);
384 set_config('system','no_utf', $no_utf);
385 set_config('system','verifyssl', $verifyssl);
386 set_config('system','proxyuser', $proxyuser);
387 set_config('system','proxy', $proxy);
388 set_config('system','curl_timeout', $timeout);
389 set_config('system','dfrn_only', $dfrn_only);
390 set_config('system','ostatus_disabled', $ostatus_disabled);
391 set_config('system','diaspora_enabled', $diaspora_enabled);
392 set_config('config','private_addons', $private_addons);
394 set_config('system','new_share', $new_share);
395 set_config('system','hide_help', $hide_help);
396 set_config('system','use_fulltext_engine', $use_fulltext_engine);
397 set_config('system','itemcache', $itemcache);
398 set_config('system','itemcache_duration', $itemcache_duration);
399 set_config('system','lockpath', $lockpath);
400 set_config('system','temppath', $temppath);
401 set_config('system','basepath', $basepath);
403 info( t('Site settings updated.') . EOL);
404 goaway($a->get_baseurl(true) . '/admin/site' );
405 return; // NOTREACHED
413 function admin_page_site(&$a) {
415 /* Installed langs */
416 $lang_choices = array();
417 $langs = glob('view/*/strings.php');
419 if(is_array($langs) && count($langs)) {
420 if(! in_array('view/en/strings.php',$langs))
421 $langs[] = 'view/en/';
423 foreach($langs as $l) {
424 $t = explode("/",$l);
425 $lang_choices[$t[1]] = $t[1];
429 /* Installed themes */
430 $theme_choices = array();
431 $theme_choices_mobile = array();
432 $theme_choices_mobile["---"] = t("No special theme for mobile devices");
433 $files = glob('view/theme/*');
435 foreach($files as $file) {
436 $f = basename($file);
437 $theme_name = ((file_exists($file . '/experimental')) ? sprintf("%s - \x28Experimental\x29", $f) : $f);
438 if (file_exists($file . '/mobile')) {
439 $theme_choices_mobile[$f] = $theme_name;
442 $theme_choices[$f] = $theme_name;
447 /* get user names to make the install a personal install of X */
448 $user_names = array();
449 $user_names['---'] = t('Multi user instance');
450 $users = q("SELECT username, nickname FROM `user`");
451 foreach ($users as $user) {
452 $user_names[$user['nickname']] = $user['username'];
456 $banner = get_config('system','banner');
458 $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>';
459 $banner = htmlspecialchars($banner);
461 //echo "<pre>"; var_dump($lang_choices); die("</pre>");
463 /* Register policy */
464 $register_choices = Array(
465 REGISTER_CLOSED => t("Closed"),
466 REGISTER_APPROVE => t("Requires approval"),
467 REGISTER_OPEN => t("Open")
470 $ssl_choices = array(
471 SSL_POLICY_NONE => t("No SSL policy, links will track page SSL state"),
472 SSL_POLICY_FULL => t("Force all links to use SSL"),
473 SSL_POLICY_SELFSIGN => t("Self-signed certificate, use SSL for local links only (discouraged)")
476 $t = get_markup_template("admin_site.tpl");
477 return replace_macros($t, array(
478 '$title' => t('Administration'),
479 '$page' => t('Site'),
480 '$submit' => t('Submit'),
481 '$registration' => t('Registration'),
482 '$upload' => t('File upload'),
483 '$corporate' => t('Policies'),
484 '$advanced' => t('Advanced'),
485 '$performance' => t('Performance'),
487 '$baseurl' => $a->get_baseurl(true),
488 // name, label, value, help string, extra data...
489 '$sitename' => array('sitename', t("Site name"), htmlentities($a->config['sitename'], ENT_QUOTES), 'UTF-8'),
490 '$banner' => array('banner', t("Banner/Logo"), $banner, ""),
491 '$language' => array('language', t("System language"), get_config('system','language'), "", $lang_choices),
492 '$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),
493 '$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile-theme'), t("Theme for mobile devices"), $theme_choices_mobile),
494 '$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),
495 '$new_share' => array('new_share', t("'Share' element"), get_config('system','new_share'), t("Activates the bbcode element 'share' for repeating items.")),
496 '$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.")),
497 '$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),
498 '$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.")),
499 '$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.")),
500 '$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.")),
502 '$register_policy' => array('register_policy', t("Register policy"), $a->config['register_policy'], "", $register_choices),
503 '$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.")),
504 '$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.")),
505 '$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.')),
506 '$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")),
507 '$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")),
508 '$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.")),
509 '$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.")),
510 '$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.")),
511 '$thread_allow' => array('thread_allow', t("Allow threaded items"), get_config('system','thread_allow'), t("Allow infinite level threading for items on this site.")),
512 '$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.")),
513 '$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.")),
514 '$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.")),
515 '$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.")),
517 '$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.")),
518 '$no_openid' => array('no_openid', t("OpenID support"), !get_config('system','no_openid'), t("OpenID support for registration and logins.")),
519 '$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")),
520 '$no_utf' => array('no_utf', t("UTF-8 Regular expressions"), !get_config('system','no_utf'), t("Use PHP UTF8 regular expressions")),
521 '$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.")),
522 '$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.")),
523 '$diaspora_enabled' => array('diaspora_enabled', t("Enable Diaspora support"), get_config('system','diaspora_enabled'), t("Provide built-in Diaspora network compatibility.")),
524 '$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.")),
525 '$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.")),
526 '$proxyuser' => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""),
527 '$proxy' => array('proxy', t("Proxy URL"), get_config('system','proxy'), ""),
528 '$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).")),
529 '$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.")),
530 '$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.")),
531 '$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.")),
533 '$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.")),
534 '$itemcache' => array('itemcache', t("Path to item cache"), get_config('system','itemcache'), "The item caches buffers generated bbcode and external images."),
535 '$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).")),
536 '$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."),
537 '$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."),
538 '$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."),
539 '$form_security_token' => get_form_security_token("admin_site"),
546 function admin_page_dbsync(&$a) {
550 if($a->argc > 3 && intval($a->argv[3]) && $a->argv[2] === 'mark') {
551 set_config('database', 'update_' . intval($a->argv[3]), 'success');
552 $curr = get_config('system','build');
553 if(intval($curr) == intval($a->argv[3]))
554 set_config('system','build',intval($curr) + 1);
555 info( t('Update has been marked successful') . EOL);
556 goaway($a->get_baseurl(true) . '/admin/dbsync');
559 if($a->argc > 2 && intval($a->argv[2])) {
560 require_once('update.php');
561 $func = 'update_' . intval($a->argv[2]);
562 if(function_exists($func)) {
564 if($retval === UPDATE_FAILED) {
565 $o .= sprintf( t('Executing %s failed. Check system logs.'), $func);
567 elseif($retval === UPDATE_SUCCESS) {
568 $o .= sprintf( t('Update %s was successfully applied.', $func));
569 set_config('database',$func, 'success');
572 $o .= sprintf( t('Update %s did not return a status. Unknown if it succeeded.'), $func);
575 $o .= sprintf( t('Update function %s could not be found.'), $func);
580 $r = q("select * from config where `cat` = 'database' ");
583 $upd = intval(substr($rr['k'],7));
584 if($upd < 1139 || $rr['v'] === 'success')
590 return '<h3>' . t('No failed updates.') . '</h3>';
592 $o = replace_macros(get_markup_template('failed_updates.tpl'),array(
593 '$base' => $a->get_baseurl(true),
594 '$banner' => t('Failed Updates'),
595 '$desc' => t('This does not include updates prior to 1139, which did not return a status.'),
596 '$mark' => t('Mark success (if update was manually applied)'),
597 '$apply' => t('Attempt to execute this update step automatically'),
610 function admin_page_users_post(&$a){
611 $pending = ( x($_POST, 'pending') ? $_POST['pending'] : Array() );
612 $users = ( x($_POST, 'user') ? $_POST['user'] : Array() );
614 check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
616 if (x($_POST,'page_users_block')){
617 foreach($users as $uid){
618 q("UPDATE `user` SET `blocked`=1-`blocked` WHERE `uid`=%s",
622 notice( sprintf( tt("%s user blocked/unblocked", "%s users blocked/unblocked", count($users)), count($users)) );
624 if (x($_POST,'page_users_delete')){
625 require_once("include/Contact.php");
626 foreach($users as $uid){
629 notice( sprintf( tt("%s user deleted", "%s users deleted", count($users)), count($users)) );
632 if (x($_POST,'page_users_approve')){
633 require_once("mod/regmod.php");
634 foreach($pending as $hash){
638 if (x($_POST,'page_users_deny')){
639 require_once("mod/regmod.php");
640 foreach($pending as $hash){
644 goaway($a->get_baseurl(true) . '/admin/users' );
645 return; // NOTREACHED
652 function admin_page_users(&$a){
655 $user = q("SELECT * FROM `user` WHERE `uid`=%d", intval($uid));
656 if (count($user)==0){
657 notice( 'User not found' . EOL);
658 goaway($a->get_baseurl(true) . '/admin/users' );
659 return ''; // NOTREACHED
663 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
665 require_once("include/Contact.php");
668 notice( sprintf(t("User '%s' deleted"), $user[0]['username']) . EOL);
671 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
672 q("UPDATE `user` SET `blocked`=%d WHERE `uid`=%s",
673 intval( 1-$user[0]['blocked'] ),
676 notice( sprintf( ($user[0]['blocked']?t("User '%s' unblocked"):t("User '%s' blocked")) , $user[0]['username']) . EOL);
679 goaway($a->get_baseurl(true) . '/admin/users' );
680 return ''; // NOTREACHED
685 $pending = q("SELECT `register`.*, `contact`.`name`, `user`.`email`
687 LEFT JOIN `contact` ON `register`.`uid` = `contact`.`uid`
688 LEFT JOIN `user` ON `register`.`uid` = `user`.`uid`;");
693 $total = q("SELECT count(*) as total FROM `user` where 1");
695 $a->set_pager_total($total[0]['total']);
696 $a->set_pager_itemspage(100);
700 $users = q("SELECT `user` . * , `contact`.`name` , `contact`.`url` , `contact`.`micro`, `lastitem`.`lastitem_date`, `user`.`account_expired`
702 (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid`
704 WHERE `item`.`type` = 'wall'
705 GROUP BY `item`.`uid`) AS `lastitem`
706 RIGHT OUTER JOIN `user` ON `user`.`uid` = `lastitem`.`uid`,
709 `user`.`uid` = `contact`.`uid`
710 AND `user`.`verified` =1
711 AND `contact`.`self` =1
712 ORDER BY `contact`.`name` LIMIT %d, %d
714 intval($a->pager['start']),
715 intval($a->pager['itemspage'])
718 function _setup_users($e){
722 t('Soapbox Account'),
723 t('Community/Celebrity Account'),
724 t('Automatic Friend Account')
726 $e['page-flags'] = $accounts[$e['page-flags']];
727 $e['register_date'] = relative_date($e['register_date']);
728 $e['login_date'] = relative_date($e['login_date']);
729 $e['lastitem_date'] = relative_date($e['lastitem_date']);
730 $e['is_admin'] = ($e['email'] === $a->config['admin_email']);
733 $users = array_map("_setup_users", $users);
736 // Get rid of dashes in key names, Smarty3 can't handle them
737 foreach($users as $key => $user) {
739 foreach($user as $k => $v) {
740 $k = str_replace('-','_',$k);
743 $users[$key] = $new_user;
746 $t = get_markup_template("admin_users.tpl");
747 $o = replace_macros($t, array(
749 '$title' => t('Administration'),
750 '$page' => t('Users'),
751 '$submit' => t('Submit'),
752 '$select_all' => t('select all'),
753 '$h_pending' => t('User registrations waiting for confirm'),
754 '$th_pending' => array( t('Request date'), t('Name'), t('Email') ),
755 '$no_pending' => t('No registrations.'),
756 '$approve' => t('Approve'),
757 '$deny' => t('Deny'),
758 '$delete' => t('Delete'),
759 '$block' => t('Block'),
760 '$unblock' => t('Unblock'),
761 '$siteadmin' => t('Site admin'),
762 '$accountexpired' => t('Account expired'),
764 '$h_users' => t('Users'),
765 '$th_users' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'), t('Account') ),
767 '$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?'),
768 '$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?'),
770 '$form_security_token' => get_form_security_token("admin_users"),
773 '$baseurl' => $a->get_baseurl(true),
775 '$pending' => $pending,
789 function admin_page_plugins(&$a){
795 $plugin = $a->argv[2];
796 if (!is_file("addon/$plugin/$plugin.php")){
797 notice( t("Item not found.") );
801 if (x($_GET,"a") && $_GET['a']=="t"){
802 check_form_security_token_redirectOnErr('/admin/plugins', 'admin_themes', 't');
804 // Toggle plugin status
805 $idx = array_search($plugin, $a->plugins);
807 unset($a->plugins[$idx]);
808 uninstall_plugin($plugin);
809 info( sprintf( t("Plugin %s disabled."), $plugin ) );
811 $a->plugins[] = $plugin;
812 install_plugin($plugin);
813 info( sprintf( t("Plugin %s enabled."), $plugin ) );
815 set_config("system","addon", implode(", ",$a->plugins));
816 goaway($a->get_baseurl(true) . '/admin/plugins' );
817 return ''; // NOTREACHED
819 // display plugin details
820 require_once('library/markdown.php');
822 if (in_array($plugin, $a->plugins)){
823 $status="on"; $action= t("Disable");
825 $status="off"; $action= t("Enable");
829 if (is_file("addon/$plugin/README.md")){
830 $readme = file_get_contents("addon/$plugin/README.md");
831 $readme = Markdown($readme);
832 } else if (is_file("addon/$plugin/README")){
833 $readme = "<pre>". file_get_contents("addon/$plugin/README") ."</pre>";
837 if (is_array($a->plugins_admin) && in_array($plugin, $a->plugins_admin)){
838 @require_once("addon/$plugin/$plugin.php");
839 $func = $plugin.'_plugin_admin';
840 $func($a, $admin_form);
843 $t = get_markup_template("admin_plugins_details.tpl");
845 return replace_macros($t, array(
846 '$title' => t('Administration'),
847 '$page' => t('Plugins'),
848 '$toggle' => t('Toggle'),
849 '$settings' => t('Settings'),
850 '$baseurl' => $a->get_baseurl(true),
852 '$plugin' => $plugin,
853 '$status' => $status,
854 '$action' => $action,
855 '$info' => get_plugin_info($plugin),
856 '$str_author' => t('Author: '),
857 '$str_maintainer' => t('Maintainer: '),
859 '$admin_form' => $admin_form,
860 '$function' => 'plugins',
862 '$readme' => $readme,
864 '$form_security_token' => get_form_security_token("admin_themes"),
875 $files = glob("addon/*/");
877 foreach($files as $file) {
879 list($tmp, $id)=array_map("trim", explode("/",$file));
880 $info = get_plugin_info($id);
881 $plugins[] = array( $id, (in_array($id, $a->plugins)?"on":"off") , $info);
886 $t = get_markup_template("admin_plugins.tpl");
887 return replace_macros($t, array(
888 '$title' => t('Administration'),
889 '$page' => t('Plugins'),
890 '$submit' => t('Submit'),
891 '$baseurl' => $a->get_baseurl(true),
892 '$function' => 'plugins',
893 '$plugins' => $plugins,
894 '$form_security_token' => get_form_security_token("admin_themes"),
899 * @param array $themes
903 function toggle_theme(&$themes,$th,&$result) {
904 for($x = 0; $x < count($themes); $x ++) {
905 if($themes[$x]['name'] === $th) {
906 if($themes[$x]['allowed']) {
907 $themes[$x]['allowed'] = 0;
911 $themes[$x]['allowed'] = 1;
919 * @param array $themes
923 function theme_status($themes,$th) {
924 for($x = 0; $x < count($themes); $x ++) {
925 if($themes[$x]['name'] === $th) {
926 if($themes[$x]['allowed']) {
939 * @param array $themes
942 function rebuild_theme_table($themes) {
945 foreach($themes as $th) {
963 function admin_page_themes(&$a){
965 $allowed_themes_str = get_config('system','allowed_themes');
966 $allowed_themes_raw = explode(',',$allowed_themes_str);
967 $allowed_themes = array();
968 if(count($allowed_themes_raw))
969 foreach($allowed_themes_raw as $x)
971 $allowed_themes[] = trim($x);
974 $files = glob('view/theme/*');
976 foreach($files as $file) {
977 $f = basename($file);
978 $is_experimental = intval(file_exists($file . '/experimental'));
979 $is_supported = 1-(intval(file_exists($file . '/unsupported'))); // Is not used yet
980 $is_allowed = intval(in_array($f,$allowed_themes));
981 $themes[] = array('name' => $f, 'experimental' => $is_experimental, 'supported' => $is_supported, 'allowed' => $is_allowed);
985 if(! count($themes)) {
986 notice( t('No themes found.'));
995 $theme = $a->argv[2];
996 if(! is_dir("view/theme/$theme")){
997 notice( t("Item not found.") );
1001 if (x($_GET,"a") && $_GET['a']=="t"){
1002 check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't');
1004 // Toggle theme status
1006 toggle_theme($themes,$theme,$result);
1007 $s = rebuild_theme_table($themes);
1009 install_theme($theme);
1010 info( sprintf('Theme %s enabled.',$theme));
1013 uninstall_theme($theme);
1014 info( sprintf('Theme %s disabled.',$theme));
1017 set_config('system','allowed_themes',$s);
1018 goaway($a->get_baseurl(true) . '/admin/themes' );
1019 return ''; // NOTREACHED
1022 // display theme details
1023 require_once('library/markdown.php');
1025 if (theme_status($themes,$theme)) {
1026 $status="on"; $action= t("Disable");
1028 $status="off"; $action= t("Enable");
1032 if (is_file("view/theme/$theme/README.md")){
1033 $readme = file_get_contents("view/theme/$theme/README.md");
1034 $readme = Markdown($readme);
1035 } else if (is_file("view/theme/$theme/README")){
1036 $readme = "<pre>". file_get_contents("view/theme/$theme/README") ."</pre>";
1040 if (is_file("view/theme/$theme/config.php")){
1041 require_once("view/theme/$theme/config.php");
1042 if(function_exists("theme_admin")){
1043 $admin_form = theme_admin($a);
1048 $screenshot = array( get_theme_screenshot($theme), t('Screenshot'));
1049 if(! stristr($screenshot[0],$theme))
1052 $t = get_markup_template("admin_plugins_details.tpl");
1053 return replace_macros($t, array(
1054 '$title' => t('Administration'),
1055 '$page' => t('Themes'),
1056 '$toggle' => t('Toggle'),
1057 '$settings' => t('Settings'),
1058 '$baseurl' => $a->get_baseurl(true),
1060 '$plugin' => $theme,
1061 '$status' => $status,
1062 '$action' => $action,
1063 '$info' => get_theme_info($theme),
1064 '$function' => 'themes',
1065 '$admin_form' => $admin_form,
1066 '$str_author' => t('Author: '),
1067 '$str_maintainer' => t('Maintainer: '),
1068 '$screenshot' => $screenshot,
1069 '$readme' => $readme,
1071 '$form_security_token' => get_form_security_token("admin_themes"),
1081 foreach($themes as $th) {
1082 $xthemes[] = array($th['name'],(($th['allowed']) ? "on" : "off"), get_theme_info($th['name']));
1086 $t = get_markup_template("admin_plugins.tpl");
1087 return replace_macros($t, array(
1088 '$title' => t('Administration'),
1089 '$page' => t('Themes'),
1090 '$submit' => t('Submit'),
1091 '$baseurl' => $a->get_baseurl(true),
1092 '$function' => 'themes',
1093 '$plugins' => $xthemes,
1094 '$experimental' => t('[Experimental]'),
1095 '$unsupported' => t('[Unsupported]'),
1096 '$form_security_token' => get_form_security_token("admin_themes"),
1107 function admin_page_logs_post(&$a) {
1108 if (x($_POST,"page_logs")) {
1109 check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
1111 $logfile = ((x($_POST,'logfile')) ? notags(trim($_POST['logfile'])) : '');
1112 $debugging = ((x($_POST,'debugging')) ? true : false);
1113 $loglevel = ((x($_POST,'loglevel')) ? intval(trim($_POST['loglevel'])) : 0);
1115 set_config('system','logfile', $logfile);
1116 set_config('system','debugging', $debugging);
1117 set_config('system','loglevel', $loglevel);
1122 info( t("Log settings updated.") );
1123 goaway($a->get_baseurl(true) . '/admin/logs' );
1124 return; // NOTREACHED
1131 function admin_page_logs(&$a){
1133 $log_choices = Array(
1134 LOGGER_NORMAL => 'Normal',
1135 LOGGER_TRACE => 'Trace',
1136 LOGGER_DEBUG => 'Debug',
1137 LOGGER_DATA => 'Data',
1141 $t = get_markup_template("admin_logs.tpl");
1143 $f = get_config('system','logfile');
1147 if(!file_exists($f)) {
1148 $data = t("Error trying to open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f exist and is
1152 $fp = fopen($f, 'r');
1154 $data = t("Couldn't open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f is readable.");
1157 $fstat = fstat($fp);
1158 $size = $fstat['size'];
1161 if($size > 5000000 || $size < 0)
1163 $seek = fseek($fp,0-$size,SEEK_END);
1165 $data = escape_tags(fread($fp,$size));
1167 $data .= escape_tags(fread($fp,4096));
1174 return replace_macros($t, array(
1175 '$title' => t('Administration'),
1176 '$page' => t('Logs'),
1177 '$submit' => t('Submit'),
1178 '$clear' => t('Clear'),
1180 '$baseurl' => $a->get_baseurl(true),
1181 '$logname' => get_config('system','logfile'),
1183 // name, label, value, help string, extra data...
1184 '$debugging' => array('debugging', t("Debugging"),get_config('system','debugging'), ""),
1185 '$logfile' => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Friendica top-level directory.")),
1186 '$loglevel' => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices),
1188 '$form_security_token' => get_form_security_token("admin_logs"),
1195 function admin_page_remoteupdate_post(&$a) {
1196 // this function should be called via ajax post
1197 if(!is_site_admin()) {
1202 if (x($_POST,'remotefile') && $_POST['remotefile']!=""){
1203 $remotefile = $_POST['remotefile'];
1204 $ftpdata = (x($_POST['ftphost'])?$_POST:false);
1205 doUpdate($remotefile, $ftpdata);
1207 echo "No remote file to download. Abort!";
1217 function admin_page_remoteupdate(&$a) {
1218 if(!is_site_admin()) {
1219 return login(false);
1222 $canwrite = canWeWrite();
1223 $canftp = function_exists('ftp_connect');
1228 $needupdate = false;
1229 $u = array('','','');
1232 $tpl = get_markup_template("admin_remoteupdate.tpl");
1233 return replace_macros($tpl, array(
1234 '$baseurl' => $a->get_baseurl(true),
1235 '$submit' => t("Update now"),
1236 '$close' => t("Close"),
1237 '$localversion' => FRIENDICA_VERSION,
1238 '$remoteversion' => $u[1],
1239 '$needupdate' => $needupdate,
1240 '$canwrite' => $canwrite,
1241 '$canftp' => $canftp,
1242 '$ftphost' => array('ftphost', t("FTP Host"), '',''),
1243 '$ftppath' => array('ftppath', t("FTP Path"), '/',''),
1244 '$ftpuser' => array('ftpuser', t("FTP User"), '',''),
1245 '$ftppwd' => array('ftppwd', t("FTP Password"), '',''),
1246 '$remotefile'=>array('remotefile','', $u['2'],''),