]> git.mxchange.org Git - friendica.git/blob - mod/admin.php
5a2ccf8932606f3ca01e1bc066b4ed8cea619f3f
[friendica.git] / mod / admin.php
1 <?php
2
3  /**
4   * Friendica admin
5   */
6 require_once("include/remoteupdate.php");
7 require_once("include/enotify.php");
8 require_once("include/text.php");
9
10
11 /**
12  * @param App $a
13  */
14 function admin_post(&$a){
15
16
17         if(!is_site_admin()) {
18                 return;
19         }
20
21         // do not allow a page manager to access the admin panel at all.
22
23         if(x($_SESSION,'submanage') && intval($_SESSION['submanage']))
24                 return;
25
26
27
28         // urls
29         if ($a->argc > 1){
30                 switch ($a->argv[1]){
31                         case 'site':
32                                 admin_page_site_post($a);
33                                 break;
34                         case 'users':
35                                 admin_page_users_post($a);
36                                 break;
37                         case 'plugins':
38                                 if ($a->argc > 2 &&
39                                         is_file("addon/".$a->argv[2]."/".$a->argv[2].".php")){
40                                                 @include_once("addon/".$a->argv[2]."/".$a->argv[2].".php");
41                                                 if(function_exists($a->argv[2].'_plugin_admin_post')) {
42                                                         $func = $a->argv[2].'_plugin_admin_post';
43                                                         $func($a);
44                                                 }
45                                 }
46                                 goaway($a->get_baseurl(true) . '/admin/plugins/' . $a->argv[2] );
47                                 return; // NOTREACHED
48                                 break;
49                         case 'themes':
50                                 if ($a->argc < 2) {
51                                         if(is_ajax()) return;
52                                         goaway($a->get_baseurl(true) . '/admin/' );
53                                         return;
54                                 }
55
56                                 $theme = $a->argv[2];
57                                 if (is_file("view/theme/$theme/config.php")){
58                                         function __call_theme_admin_post(&$a, $theme) {
59                                                 $orig_theme = $a->theme;
60                                                 $orig_page = $a->page;
61                                                 $orig_session_theme = $_SESSION['theme'];
62                                                 require_once("view/theme/$theme/theme.php");
63                                                 require_once("view/theme/$theme/config.php");
64                                                 $_SESSION['theme'] = $theme;
65
66
67                                                 $init = $theme."_init";
68                                                 if(function_exists($init)) $init($a);
69                                                 if(function_exists("theme_admin_post")){
70                                                         $admin_form = theme_admin_post($a);
71                                                 }
72
73                                                 $_SESSION['theme'] = $orig_session_theme;
74                                                 $a->theme = $orig_theme;
75                                                 $a->page = $orig_page;
76                                                 return $admin_form;
77                                         }
78                                         __call_theme_admin_post($a, $theme);
79                                 }
80                                 info(t('Theme settings updated.'));
81                                 if(is_ajax()) return;
82
83                                 goaway($a->get_baseurl(true) . '/admin/themes/' . $theme );
84                                 return;
85                                 break;
86                         case 'logs':
87                                 admin_page_logs_post($a);
88                                 break;
89                         case 'dbsync':
90                                 admin_page_dbsync_post($a);
91                                 break;
92                         case 'update':
93                                 admin_page_remoteupdate_post($a);
94                                 break;
95                 }
96         }
97
98         goaway($a->get_baseurl(true) . '/admin' );
99         return; // NOTREACHED
100 }
101
102 /**
103  * @param App $a
104  * @return string
105  */
106 function admin_content(&$a) {
107
108         if(!is_site_admin()) {
109                 return login(false);
110         }
111
112         if(x($_SESSION,'submanage') && intval($_SESSION['submanage']))
113                 return "";
114
115         // APC deactivated, since there are problems with PHP 5.5
116         //if (function_exists("apc_delete")) {
117         //      $toDelete = new APCIterator('user', APC_ITER_VALUE);
118         //      apc_delete($toDelete);
119         //}
120
121         /**
122          * Side bar links
123          */
124
125         // array( url, name, extra css classes )
126         $aside = Array(
127                 'site'   =>     Array($a->get_baseurl(true)."/admin/site/", t("Site") , "site"),
128                 'users'  =>     Array($a->get_baseurl(true)."/admin/users/", t("Users") , "users"),
129                 'plugins'=>     Array($a->get_baseurl(true)."/admin/plugins/", t("Plugins") , "plugins"),
130                 'themes' =>     Array($a->get_baseurl(true)."/admin/themes/", t("Themes") , "themes"),
131                 'dbsync' =>     Array($a->get_baseurl(true)."/admin/dbsync/", t('DB updates'), "dbsync"),
132                 'queue'  =>     Array($a->get_baseurl(true)."/admin/queue/", t('Inspect Queue'), "queue"),
133                 //'update' =>   Array($a->get_baseurl(true)."/admin/update/", t("Software Update") , "update")
134         );
135
136         /* get plugins admin page */
137
138         $r = q("SELECT name FROM `addon` WHERE `plugin_admin`=1");
139         $aside['plugins_admin']=Array();
140         foreach ($r as $h){
141                 $plugin =$h['name'];
142                 $aside['plugins_admin'][] = Array($a->get_baseurl(true)."/admin/plugins/".$plugin, $plugin, "plugin");
143                 // temp plugins with admin
144                 $a->plugins_admin[] = $plugin;
145         }
146
147         $aside['logs'] = Array($a->get_baseurl(true)."/admin/logs/", t("Logs"), "logs");
148         $aside['diagnostics_probe'] = Array($a->get_baseurl(true).'/probe/', t('probe address'), 'probe');
149         $aside['diagnostics_webfinger'] = Array($a->get_baseurl(true).'/webfinger/', t('check webfinger'), 'webfinger');
150
151         $t = get_markup_template("admin_aside.tpl");
152         $a->page['aside'] .= replace_macros( $t, array(
153                         '$admin' => $aside,
154                         '$admtxt' => t('Admin'),
155                         '$plugadmtxt' => t('Plugin Features'),
156                         '$logtxt' => t('Logs'),
157                         '$diagnosticstxt' => t('diagnostics'),
158                         '$h_pending' => t('User registrations waiting for confirmation'),
159                         '$admurl'=> $a->get_baseurl(true)."/admin/"
160         ));
161
162
163
164         /**
165          * Page content
166          */
167         $o = '';
168         // urls
169         if ($a->argc > 1){
170                 switch ($a->argv[1]){
171                         case 'site':
172                                 $o = admin_page_site($a);
173                                 break;
174                         case 'users':
175                                 $o = admin_page_users($a);
176                                 break;
177                         case 'plugins':
178                                 $o = admin_page_plugins($a);
179                                 break;
180                         case 'themes':
181                                 $o = admin_page_themes($a);
182                                 break;
183                         case 'logs':
184                                 $o = admin_page_logs($a);
185                                 break;
186                         case 'dbsync':
187                                 $o = admin_page_dbsync($a);
188                                 break;
189                         case 'update':
190                                 $o = admin_page_remoteupdate($a);
191                                 break;
192                         case 'queue':
193                                 $o = admin_page_queue($a);
194                                 break;
195                         default:
196                                 notice( t("Item not found.") );
197                 }
198         } else {
199                 $o = admin_page_summary($a);
200         }
201
202         if(is_ajax()) {
203                 echo $o;
204                 killme();
205                 return '';
206         } else {
207                 return $o;
208         }
209 }
210
211 /**
212  * Admin Inspect Queue Page
213  * @param App $a
214  * return string
215  */
216 function admin_page_queue(&$a) {
217         // get content from the queue table
218         $r = q("SELECT c.name,c.nurl,q.id,q.network,q.created,q.last from queue as q, contact as c where c.id=q.cid order by q.cid, q.created;");
219
220         $t = get_markup_template("admin_queue.tpl");
221         return replace_macros($t, array(
222                 '$title' => t('Administration'),
223                 '$page' => t('Inspect Queue'),
224                 '$count' => sizeof($r),
225                 'id_header' => t('ID'),
226                 '$to_header' => t('Recipient Name'),
227                 '$url_header' => t('Recipient Profile'),
228                 '$network_header' => t('Network'),
229                 '$created_header' => t('Created'),
230                 '$last_header' => t('Last Tried'),
231                 '$info' => t('This page lists the content of the queue for outgoing postings. These are postings the initial delivery failed for. They will be resend later and eventually deleted if the delivery fails permanently.'),
232                 '$entries' => $r,
233         ));
234 }
235 /**
236  * Admin Summary Page
237  * @param App $a
238  * @return string
239  */
240 function admin_page_summary(&$a) {
241         $r = q("SELECT `page-flags`, COUNT(uid) as `count` FROM `user` GROUP BY `page-flags`");
242         $accounts = Array(
243                 Array( t('Normal Account'), 0),
244                 Array( t('Soapbox Account'), 0),
245                 Array( t('Community/Celebrity Account'), 0),
246                 Array( t('Automatic Friend Account'), 0),
247                 Array( t('Blog Account'), 0),
248                 Array( t('Private Forum'), 0)
249         );
250
251         $users=0;
252         foreach ($r as $u){ $accounts[$u['page-flags']][1] = $u['count']; $users+= $u['count']; }
253
254         logger('accounts: ' . print_r($accounts,true),LOGGER_DATA);
255
256         $r = q("SELECT COUNT(id) as `count` FROM `register`");
257         $pending = $r[0]['count'];
258
259         $r = q("select count(*) as total from deliverq where 1");
260         $deliverq = (($r) ? $r[0]['total'] : 0);
261
262         $r = q("select count(*) as total from queue where 1");
263         $queue = (($r) ? $r[0]['total'] : 0);
264
265         // We can do better, but this is a quick queue status
266
267         $queues = array( 'label' => t('Message queues'), 'deliverq' => $deliverq, 'queue' => $queue );
268
269
270         $t = get_markup_template("admin_summary.tpl");
271         return replace_macros($t, array(
272                 '$title' => t('Administration'),
273                 '$page' => t('Summary'),
274                 '$queues' => $queues,
275                 '$users' => Array( t('Registered users'), $users),
276                 '$accounts' => $accounts,
277                 '$pending' => Array( t('Pending registrations'), $pending),
278                 '$version' => Array( t('Version'), FRIENDICA_VERSION),
279                 '$baseurl' => $a->get_baseurl(),
280                 '$platform' => FRIENDICA_PLATFORM,
281                 '$codename' => FRIENDICA_CODENAME,
282                 '$build' =>  get_config('system','build'),
283                 '$plugins' => Array( t('Active plugins'), $a->plugins )
284         ));
285 }
286
287
288 /**
289  * Admin Site Page
290  *  @param App $a
291  */
292 function admin_page_site_post(&$a){
293         if (!x($_POST,"page_site")){
294                 return;
295         }
296
297         check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
298
299         // relocate
300         if (x($_POST,'relocate') && x($_POST,'relocate_url') && $_POST['relocate_url']!=""){
301                 $new_url = $_POST['relocate_url'];
302                 $new_url = rtrim($new_url,"/");
303
304                 $parsed = @parse_url($new_url);
305                 if (!$parsed || (!x($parsed,'host') || !x($parsed,'scheme'))) {
306                         notice(t("Can not parse base url. Must have at least <scheme>://<domain>"));
307                         goaway($a->get_baseurl(true) . '/admin/site' );
308                 }
309
310                 /* steps:
311                  * replace all "baseurl" to "new_url" in config, profile, term, items and contacts
312                  * send relocate for every local user
313                  * */
314
315                 $old_url = $a->get_baseurl(true);
316
317                 function update_table($table_name, $fields, $old_url, $new_url) {
318                         global $db, $a;
319
320                         $dbold = dbesc($old_url);
321                         $dbnew = dbesc($new_url);
322
323                         $upd = array();
324                         foreach ($fields as $f) {
325                                 $upd[] = "`$f` = REPLACE(`$f`, '$dbold', '$dbnew')";
326                         }
327
328                         $upds = implode(", ", $upd);
329
330
331
332                         $q = sprintf("UPDATE %s SET %s;", $table_name, $upds);
333                         $r = q($q);
334                         if (!$r) {
335                                 notice( "Failed updating '$table_name': " . $db->error );
336                                 goaway($a->get_baseurl(true) . '/admin/site' );
337                         }
338                 }
339
340                 // update tables
341                 update_table("profile", array('photo', 'thumb'), $old_url, $new_url);
342                 update_table("term", array('url'), $old_url, $new_url);
343                 update_table("contact", array('photo','thumb','micro','url','nurl','request','notify','poll','confirm','poco'), $old_url, $new_url);
344                 update_table("unique_contacts", array('url'), $old_url, $new_url);
345                 update_table("item", array('owner-link','owner-avatar','author-name','author-link','author-avatar','body','plink','tag'), $old_url, $new_url);
346
347                 // update config
348                 $a->set_baseurl($new_url);
349                 set_config('system','url',$new_url);
350
351                 // send relocate
352                 $users = q("SELECT uid FROM user WHERE account_removed = 0 AND account_expired = 0");
353
354                 foreach ($users as $user) {
355                         proc_run('php', 'include/notifier.php', 'relocate', $user['uid']);
356                 }
357
358                 info("Relocation started. Could take a while to complete.");
359
360                 goaway($a->get_baseurl(true) . '/admin/site' );
361         }
362         // end relocate
363
364         $sitename               =       ((x($_POST,'sitename'))                 ? notags(trim($_POST['sitename']))              : '');
365         $hostname               =       ((x($_POST,'hostname'))                 ? notags(trim($_POST['hostname']))              : '');
366         $sender_email           =       ((x($_POST,'sender_email'))             ? notags(trim($_POST['sender_email']))          : '');
367         $banner                 =       ((x($_POST,'banner'))                   ? trim($_POST['banner'])                        : false);
368         $shortcut_icon          =       ((x($_POST,'shortcut_icon'))            ? notags(trim($_POST['shortcut_icon']))         : '');
369         $touch_icon             =       ((x($_POST,'touch_icon'))               ? notags(trim($_POST['touch_icon']))            : '');
370         $info                   =       ((x($_POST,'info'))                     ? trim($_POST['info'])                  : false);
371         $language               =       ((x($_POST,'language'))                 ? notags(trim($_POST['language']))              : '');
372         $theme                  =       ((x($_POST,'theme'))                    ? notags(trim($_POST['theme']))                 : '');
373         $theme_mobile           =       ((x($_POST,'theme_mobile'))             ? notags(trim($_POST['theme_mobile']))          : '');
374         $maximagesize           =       ((x($_POST,'maximagesize'))             ? intval(trim($_POST['maximagesize']))          :  0);
375         $maximagelength         =       ((x($_POST,'maximagelength'))           ? intval(trim($_POST['maximagelength']))        :  MAX_IMAGE_LENGTH);
376         $jpegimagequality       =       ((x($_POST,'jpegimagequality'))         ? intval(trim($_POST['jpegimagequality']))      :  JPEG_QUALITY);
377
378
379         $register_policy        =       ((x($_POST,'register_policy'))          ? intval(trim($_POST['register_policy']))       :  0);
380         $daily_registrations    =       ((x($_POST,'max_daily_registrations'))  ? intval(trim($_POST['max_daily_registrations']))       :0);
381         $abandon_days           =       ((x($_POST,'abandon_days'))             ? intval(trim($_POST['abandon_days']))          :  0);
382
383         $register_text          =       ((x($_POST,'register_text'))            ? notags(trim($_POST['register_text']))         : '');
384
385         $allowed_sites          =       ((x($_POST,'allowed_sites'))            ? notags(trim($_POST['allowed_sites']))         : '');
386         $allowed_email          =       ((x($_POST,'allowed_email'))            ? notags(trim($_POST['allowed_email']))         : '');
387         $block_public           =       ((x($_POST,'block_public'))             ? True                                          : False);
388         $force_publish          =       ((x($_POST,'publish_all'))              ? True                                          : False);
389         $global_directory       =       ((x($_POST,'directory'))                ? notags(trim($_POST['directory']))     : '');
390         $thread_allow           =       ((x($_POST,'thread_allow'))             ? True                                          : False);
391         $newuser_private                =       ((x($_POST,'newuser_private'))          ? True                                          : False);
392         $enotify_no_content             =       ((x($_POST,'enotify_no_content'))       ? True                                          : False);
393         $private_addons                 =       ((x($_POST,'private_addons'))           ? True                                          : False);
394         $disable_embedded               =       ((x($_POST,'disable_embedded'))         ? True                                          : False);
395         $allow_users_remote_self        =       ((x($_POST,'allow_users_remote_self'))          ? True                                          : False);
396
397         $no_multi_reg           =       ((x($_POST,'no_multi_reg'))             ? True                                          : False);
398         $no_openid              =       !((x($_POST,'no_openid'))               ? True                                          : False);
399         $no_regfullname         =       !((x($_POST,'no_regfullname'))          ? True                                          : False);
400         $no_utf                 =       !((x($_POST,'no_utf'))                  ? True                                          : False);
401         $community_page_style   =       ((x($_POST,'community_page_style'))     ? intval(trim($_POST['community_page_style']))  : 0);
402         $max_author_posts_community_page        =       ((x($_POST,'max_author_posts_community_page'))  ? intval(trim($_POST['max_author_posts_community_page']))       : 0);
403
404         $verifyssl              =       ((x($_POST,'verifyssl'))                ? True                                          : False);
405         $proxyuser              =       ((x($_POST,'proxyuser'))                ? notags(trim($_POST['proxyuser']))             : '');
406         $proxy                  =       ((x($_POST,'proxy'))                    ? notags(trim($_POST['proxy']))                 : '');
407         $timeout                =       ((x($_POST,'timeout'))                  ? intval(trim($_POST['timeout']))               : 60);
408         $delivery_interval      =       ((x($_POST,'delivery_interval'))        ? intval(trim($_POST['delivery_interval']))     : 0);
409         $poll_interval          =       ((x($_POST,'poll_interval'))            ? intval(trim($_POST['poll_interval']))         : 0);
410         $maxloadavg             =       ((x($_POST,'maxloadavg'))               ? intval(trim($_POST['maxloadavg']))            : 50);
411         $maxloadavg_frontend    =       ((x($_POST,'maxloadavg_frontend'))      ? intval(trim($_POST['maxloadavg_frontend']))   : 50);
412         $poco_completion        =       ((x($_POST,'poco_completion'))          ? intval(trim($_POST['poco_completion']))       : false);
413         $poco_requery_days      =       ((x($_POST,'poco_requery_days'))        ? intval(trim($_POST['poco_requery_days']))     : 7);
414         $poco_discovery         =       ((x($_POST,'poco_discovery'))           ? intval(trim($_POST['poco_discovery']))        : 0);
415         $poco_discovery_since   =       ((x($_POST,'poco_discovery_since'))     ? intval(trim($_POST['poco_discovery_since']))  : 30);
416         $poco_local_search      =       ((x($_POST,'poco_local_search'))        ? intval(trim($_POST['poco_local_search']))     : false);
417         $nodeinfo               =       ((x($_POST,'nodeinfo'))                 ? intval(trim($_POST['nodeinfo']))              : false);
418         $dfrn_only              =       ((x($_POST,'dfrn_only'))                ? True                                          : False);
419         $ostatus_disabled       =       !((x($_POST,'ostatus_disabled'))        ? True                                          : False);
420         $ostatus_poll_interval  =       ((x($_POST,'ostatus_poll_interval'))    ? intval(trim($_POST['ostatus_poll_interval'])) :  0);
421         $diaspora_enabled       =       ((x($_POST,'diaspora_enabled'))         ? True                                          : False);
422         $ssl_policy             =       ((x($_POST,'ssl_policy'))               ? intval($_POST['ssl_policy'])                  : 0);
423         $force_ssl              =       ((x($_POST,'force_ssl'))                ? True                                          : False);
424         $old_share              =       ((x($_POST,'old_share'))                ? True                                          : False);
425         $hide_help              =       ((x($_POST,'hide_help'))                ? True                                          : False);
426         $suppress_language      =       ((x($_POST,'suppress_language'))        ? True                                          : False);
427         $suppress_tags          =       ((x($_POST,'suppress_tags'))            ? True                                          : False);
428         $use_fulltext_engine    =       ((x($_POST,'use_fulltext_engine'))      ? True                                          : False);
429         $itemcache              =       ((x($_POST,'itemcache'))                ? notags(trim($_POST['itemcache']))             : '');
430         $itemcache_duration     =       ((x($_POST,'itemcache_duration'))       ? intval($_POST['itemcache_duration'])          : 0);
431         $max_comments           =       ((x($_POST,'max_comments'))             ? intval($_POST['max_comments'])                : 0);
432         $lockpath               =       ((x($_POST,'lockpath'))                 ? notags(trim($_POST['lockpath']))              : '');
433         $temppath               =       ((x($_POST,'temppath'))                 ? notags(trim($_POST['temppath']))              : '');
434         $basepath               =       ((x($_POST,'basepath'))                 ? notags(trim($_POST['basepath']))              : '');
435         $singleuser             =       ((x($_POST,'singleuser'))               ? notags(trim($_POST['singleuser']))            : '');
436         $proxy_disabled         =       ((x($_POST,'proxy_disabled'))           ? True                                          : False);
437         $old_pager              =       ((x($_POST,'old_pager'))                ? True                                          : False);
438         $only_tag_search        =       ((x($_POST,'only_tag_search'))          ? True                                          : False);
439         $rino                   =       ((x($_POST,'rino'))                             ? intval($_POST['rino'])                                : 0);
440         $embedly                =       ((x($_POST,'embedly'))                  ? notags(trim($_POST['embedly']))               : '');
441
442         if ($a->get_path() != "")
443                 $diaspora_enabled = false;
444
445         if (!$thread_allow)
446                 $ostatus_disabled = true;
447
448         if($ssl_policy != intval(get_config('system','ssl_policy'))) {
449                 if($ssl_policy == SSL_POLICY_FULL) {
450                         q("update `contact` set
451                                 `url`     = replace(`url`    , 'http:' , 'https:'),
452                                 `photo`   = replace(`photo`  , 'http:' , 'https:'),
453                                 `thumb`   = replace(`thumb`  , 'http:' , 'https:'),
454                                 `micro`   = replace(`micro`  , 'http:' , 'https:'),
455                                 `request` = replace(`request`, 'http:' , 'https:'),
456                                 `notify`  = replace(`notify` , 'http:' , 'https:'),
457                                 `poll`    = replace(`poll`   , 'http:' , 'https:'),
458                                 `confirm` = replace(`confirm`, 'http:' , 'https:'),
459                                 `poco`    = replace(`poco`   , 'http:' , 'https:')
460                                 where `self` = 1"
461                         );
462                         q("update `profile` set
463                                 `photo`   = replace(`photo`  , 'http:' , 'https:'),
464                                 `thumb`   = replace(`thumb`  , 'http:' , 'https:')
465                                 where 1 "
466                         );
467                 }
468                 elseif($ssl_policy == SSL_POLICY_SELFSIGN) {
469                         q("update `contact` set
470                                 `url`     = replace(`url`    , 'https:' , 'http:'),
471                                 `photo`   = replace(`photo`  , 'https:' , 'http:'),
472                                 `thumb`   = replace(`thumb`  , 'https:' , 'http:'),
473                                 `micro`   = replace(`micro`  , 'https:' , 'http:'),
474                                 `request` = replace(`request`, 'https:' , 'http:'),
475                                 `notify`  = replace(`notify` , 'https:' , 'http:'),
476                                 `poll`    = replace(`poll`   , 'https:' , 'http:'),
477                                 `confirm` = replace(`confirm`, 'https:' , 'http:'),
478                                 `poco`    = replace(`poco`   , 'https:' , 'http:')
479                                 where `self` = 1"
480                         );
481                         q("update `profile` set
482                                 `photo`   = replace(`photo`  , 'https:' , 'http:'),
483                                 `thumb`   = replace(`thumb`  , 'https:' , 'http:')
484                                 where 1 "
485                         );
486                 }
487         }
488         set_config('system','ssl_policy',$ssl_policy);
489         set_config('system','delivery_interval',$delivery_interval);
490         set_config('system','poll_interval',$poll_interval);
491         set_config('system','maxloadavg',$maxloadavg);
492         set_config('system','maxloadavg_frontend',$maxloadavg_frontend);
493         set_config('system','poco_completion',$poco_completion);
494         set_config('system','poco_requery_days',$poco_requery_days);
495         set_config('system','poco_discovery',$poco_discovery);
496         set_config('system','poco_discovery_since',$poco_discovery_since);
497         set_config('system','poco_local_search',$poco_local_search);
498         set_config('system','nodeinfo',$nodeinfo);
499         set_config('config','sitename',$sitename);
500         set_config('config','hostname',$hostname);
501         set_config('config','sender_email', $sender_email);
502         set_config('system','suppress_language',$suppress_language);
503         set_config('system','suppress_tags',$suppress_tags);
504         set_config('system','shortcut_icon',$shortcut_icon);
505         set_config('system','touch_icon',$touch_icon);
506
507         if ($banner==""){
508                 // don't know why, but del_config doesn't work...
509                 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
510                         dbesc("system"),
511                         dbesc("banner")
512                 );
513         } else {
514                 set_config('system','banner', $banner);
515         }
516         if ($info=="") {
517                 del_config('config','info');
518         } else {
519                 set_config('config','info',$info);
520         }
521         set_config('system','language', $language);
522         set_config('system','theme', $theme);
523         if ( $theme_mobile === '---' ) {
524                 del_config('system','mobile-theme');
525         } else {
526                 set_config('system','mobile-theme', $theme_mobile);
527                 }
528                 if ( $singleuser === '---' ) {
529                         del_config('system','singleuser');
530                 } else {
531                         set_config('system','singleuser', $singleuser);
532                 }
533         set_config('system','maximagesize', $maximagesize);
534         set_config('system','max_image_length', $maximagelength);
535         set_config('system','jpeg_quality', $jpegimagequality);
536
537         set_config('config','register_policy', $register_policy);
538         set_config('system','max_daily_registrations', $daily_registrations);
539         set_config('system','account_abandon_days', $abandon_days);
540         set_config('config','register_text', $register_text);
541         set_config('system','allowed_sites', $allowed_sites);
542         set_config('system','allowed_email', $allowed_email);
543         set_config('system','block_public', $block_public);
544         set_config('system','publish_all', $force_publish);
545         set_config('system','directory', $global_directory);
546         set_config('system','thread_allow', $thread_allow);
547         set_config('system','newuser_private', $newuser_private);
548         set_config('system','enotify_no_content', $enotify_no_content);
549         set_config('system','disable_embedded', $disable_embedded);
550         set_config('system','allow_users_remote_self', $allow_users_remote_self);
551
552         set_config('system','block_extended_register', $no_multi_reg);
553         set_config('system','no_openid', $no_openid);
554         set_config('system','no_regfullname', $no_regfullname);
555         set_config('system','community_page_style', $community_page_style);
556         set_config('system','max_author_posts_community_page', $max_author_posts_community_page);
557         set_config('system','no_utf', $no_utf);
558         set_config('system','verifyssl', $verifyssl);
559         set_config('system','proxyuser', $proxyuser);
560         set_config('system','proxy', $proxy);
561         set_config('system','curl_timeout', $timeout);
562         set_config('system','dfrn_only', $dfrn_only);
563         set_config('system','ostatus_disabled', $ostatus_disabled);
564         set_config('system','ostatus_poll_interval', $ostatus_poll_interval);
565         set_config('system','diaspora_enabled', $diaspora_enabled);
566
567         set_config('config','private_addons', $private_addons);
568
569         set_config('system','force_ssl', $force_ssl);
570         set_config('system','old_share', $old_share);
571         set_config('system','hide_help', $hide_help);
572         set_config('system','use_fulltext_engine', $use_fulltext_engine);
573         set_config('system','itemcache', $itemcache);
574         set_config('system','itemcache_duration', $itemcache_duration);
575         set_config('system','max_comments', $max_comments);
576         set_config('system','lockpath', $lockpath);
577         set_config('system','temppath', $temppath);
578         set_config('system','basepath', $basepath);
579         set_config('system','proxy_disabled', $proxy_disabled);
580         set_config('system','old_pager', $old_pager);
581         set_config('system','only_tag_search', $only_tag_search);
582
583
584         if ($rino==2 and !function_exists('mcrypt_create_iv')){
585                 notice(t("RINO2 needs mcrypt php extension to work."));
586         } else {
587                 set_config('system','rino_encrypt', $rino);
588         }
589
590         set_config('system','embedly', $embedly);
591
592
593         info( t('Site settings updated.') . EOL);
594         goaway($a->get_baseurl(true) . '/admin/site' );
595         return; // NOTREACHED
596
597 }
598
599 /**
600  * @param  App $a
601  * @return string
602  */
603 function admin_page_site(&$a) {
604
605         /* Installed langs */
606         $lang_choices = get_avaiable_languages();
607
608         if (strlen(get_config('system','directory_submit_url')) AND
609                 !strlen(get_config('system','directory'))) {
610                 set_config('system','directory', dirname(get_config('system','directory_submit_url')));
611                 del_config('system','directory_submit_url');
612         }
613
614         /* Installed themes */
615         $theme_choices = array();
616         $theme_choices_mobile = array();
617         $theme_choices_mobile["---"] = t("No special theme for mobile devices");
618         $files = glob('view/theme/*');
619         if($files) {
620                 foreach($files as $file) {
621                         $f = basename($file);
622                         $theme_name = ((file_exists($file . '/experimental')) ?  sprintf("%s - \x28Experimental\x29", $f) : $f);
623                         if (file_exists($file . '/mobile')) {
624                                 $theme_choices_mobile[$f] = $theme_name;
625                         }
626                 else {
627                                 $theme_choices[$f] = $theme_name;
628                         }
629                 }
630                 }
631
632                 /* Community page style */
633                 $community_page_style_choices = array(
634                         CP_NO_COMMUNITY_PAGE => t("No community page"),
635                         CP_USERS_ON_SERVER => t("Public postings from users of this site"),
636                         CP_GLOBAL_COMMUNITY => t("Global community page")
637                         );
638
639                 /* OStatus conversation poll choices */
640                 $ostatus_poll_choices = array(
641                         "-2" => t("Never"),
642                         "-1" => t("At post arrival"),
643                         "0" => t("Frequently"),
644                         "60" => t("Hourly"),
645                         "720" => t("Twice daily"),
646                         "1440" => t("Daily")
647                         );
648
649                 $poco_discovery_choices = array(
650                         "0" => t("Disabled"),
651                         "1" => t("Users"),
652                         "2" => t("Users, Global Contacts"),
653                         "3" => t("Users, Global Contacts/fallback"),
654                         );
655
656                 $poco_discovery_since_choices = array(
657                         "30" => t("One month"),
658                         "91" => t("Three months"),
659                         "182" => t("Half a year"),
660                         "365" => t("One year"),
661                         );
662
663                 /* get user names to make the install a personal install of X */
664                 $user_names = array();
665                 $user_names['---'] = t('Multi user instance');
666                 $users = q("SELECT username, nickname FROM `user`");
667                 foreach ($users as $user) {
668                         $user_names[$user['nickname']] = $user['username'];
669                 }
670
671         /* Banner */
672         $banner = get_config('system','banner');
673         if($banner == false)
674                 $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>';
675         $banner = htmlspecialchars($banner);
676         $info = get_config('config','info');
677         $info = htmlspecialchars($info);
678
679         // Automatically create temporary paths
680         get_temppath();
681         get_lockpath();
682         get_itemcachepath();
683
684         //echo "<pre>"; var_dump($lang_choices); die("</pre>");
685
686         /* Register policy */
687         $register_choices = Array(
688                 REGISTER_CLOSED => t("Closed"),
689                 REGISTER_APPROVE => t("Requires approval"),
690                 REGISTER_OPEN => t("Open")
691         );
692
693         $ssl_choices = array(
694                 SSL_POLICY_NONE => t("No SSL policy, links will track page SSL state"),
695                 SSL_POLICY_FULL => t("Force all links to use SSL"),
696                 SSL_POLICY_SELFSIGN => t("Self-signed certificate, use SSL for local links only (discouraged)")
697         );
698
699         if ($a->config['hostname'] == "")
700                 $a->config['hostname'] = $a->get_hostname();
701
702         $diaspora_able = ($a->get_path() == "");
703
704         $t = get_markup_template("admin_site.tpl");
705         return replace_macros($t, array(
706                 '$title' => t('Administration'),
707                 '$page' => t('Site'),
708                 '$submit' => t('Save Settings'),
709                 '$registration' => t('Registration'),
710                 '$upload' => t('File upload'),
711                 '$corporate' => t('Policies'),
712                 '$advanced' => t('Advanced'),
713                 '$portable_contacts' => t('Auto Discovered Contact Directory'),
714                 '$performance' => t('Performance'),
715                 '$relocate'=> t('Relocate - WARNING: advanced function. Could make this server unreachable.'),
716                 '$baseurl' => $a->get_baseurl(true),
717                 // name, label, value, help string, extra data...
718                 '$sitename'             => array('sitename', t("Site name"), $a->config['sitename'],''),
719                 '$hostname'             => array('hostname', t("Host name"), $a->config['hostname'], ""),
720                 '$sender_email'         => array('sender_email', t("Sender Email"), $a->config['sender_email'], t("The email address your server shall use to send notification emails from."), "", "", "email"),
721                 '$banner'               => array('banner', t("Banner/Logo"), $banner, ""),
722                 '$shortcut_icon'        => array('shortcut_icon', t("Shortcut icon"), get_config('system','shortcut_icon'),  t("Link to an icon that will be used for browsers.")),
723                 '$touch_icon'           => array('touch_icon', t("Touch icon"), get_config('system','touch_icon'),  t("Link to an icon that will be used for tablets and mobiles.")),
724                 '$info' => array('info',t('Additional Info'), $info, sprintf(t('For public servers: you can add additional information here that will be listed at %s/siteinfo.'), get_server())),
725                 '$language'             => array('language', t("System language"), get_config('system','language'), "", $lang_choices),
726                 '$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),
727                 '$theme_mobile'         => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile-theme'), t("Theme for mobile devices"), $theme_choices_mobile),
728                 '$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),
729                 '$force_ssl'            => array('force_ssl', t("Force SSL"), get_config('system','force_ssl'), t("Force all Non-SSL requests to SSL - Attention: on some systems it could lead to endless loops.")),
730                 '$old_share'            => array('old_share', t("Old style 'Share'"), get_config('system','old_share'), t("Deactivates the bbcode element 'share' for repeating items.")),
731                 '$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.")),
732                 '$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),
733                 '$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.")),
734                 '$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.")),
735                 '$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.")),
736
737                 '$register_policy'      => array('register_policy', t("Register policy"), $a->config['register_policy'], "", $register_choices),
738                 '$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.")),
739                 '$register_text'        => array('register_text', t("Register text"), $a->config['register_text'], t("Will be displayed prominently on the registration page.")),
740                 '$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.')),
741                 '$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")),
742                 '$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")),
743                 '$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.")),
744                 '$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.")),
745                 '$global_directory'     => array('directory', t("Global directory URL"), get_config('system','directory'), t("URL to the global directory. If this is not set, the global directory is completely unavailable to the application.")),
746                 '$thread_allow'         => array('thread_allow', t("Allow threaded items"), get_config('system','thread_allow'), t("Allow infinite level threading for items on this site.")),
747                 '$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.")),
748                 '$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.")),
749                 '$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.")),
750                 '$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.")),
751                 '$allow_users_remote_self'      => array('allow_users_remote_self', t('Allow Users to set remote_self'), get_config('system','allow_users_remote_self'), t('With checking this, every user is allowed to mark every contact as a remote_self in the repair contact dialog. Setting this flag on a contact causes mirroring every posting of that contact in the users stream.')),
752                 '$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.")),
753                 '$no_openid'            => array('no_openid', t("OpenID support"), !get_config('system','no_openid'), t("OpenID support for registration and logins.")),
754                 '$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")),
755                 '$no_utf'               => array('no_utf', t("UTF-8 Regular expressions"), !get_config('system','no_utf'), t("Use PHP UTF8 regular expressions")),
756                 '$community_page_style' => array('community_page_style', t("Community Page Style"), get_config('system','community_page_style'), t("Type of community page to show. 'Global community' shows every public posting from an open distributed network that arrived on this server."), $community_page_style_choices),
757                 '$max_author_posts_community_page' => array('max_author_posts_community_page', t("Posts per user on community page"), get_config('system','max_author_posts_community_page'), t("The maximum number of posts per user on the community page. (Not valid for 'Global Community')")),
758                 '$ostatus_disabled'     => array('ostatus_disabled', t("Enable OStatus support"), !get_config('system','ostatus_disabled'), t("Provide built-in OStatus \x28StatusNet, GNU Social etc.\x29 compatibility. All communications in OStatus are public, so privacy warnings will be occasionally displayed.")),
759                 '$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),
760                 '$ostatus_not_able'     => t("OStatus support can only be enabled if threading is enabled."),
761                 '$diaspora_able'        => $diaspora_able,
762                 '$diaspora_not_able'    => t("Diaspora support can't be enabled because Friendica was installed into a sub directory."),
763                 '$diaspora_enabled'     => array('diaspora_enabled', t("Enable Diaspora support"), get_config('system','diaspora_enabled'), t("Provide built-in Diaspora network compatibility.")),
764                 '$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.")),
765                 '$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.")),
766                 '$proxyuser'            => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""),
767                 '$proxy'                => array('proxy', t("Proxy URL"), get_config('system','proxy'), ""),
768                 '$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).")),
769                 '$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.")),
770                 '$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.")),
771                 '$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.")),
772                 '$maxloadavg_frontend'  => array('maxloadavg_frontend', t("Maximum Load Average (Frontend)"), ((intval(get_config('system','maxloadavg_frontend')) > 0)?get_config('system','maxloadavg_frontend'):50), t("Maximum system load before the frontend quits service - default 50.")),
773
774                 '$poco_completion'      => array('poco_completion', t("Periodical check of global contacts"), get_config('system','poco_completion'), t("If enabled, the global contacts are checked periodically for missing or outdated data and the vitality of the contacts and servers.")),
775                 '$poco_requery_days'    => array('poco_requery_days', t("Days between requery"), get_config('system','poco_requery_days'), t("Number of days after which a server is requeried for his contacts.")),
776                 '$poco_discovery'       => array('poco_discovery', t("Discover contacts from other servers"), (string) intval(get_config('system','poco_discovery')), t("Periodically query other servers for contacts. You can choose between 'users': the users on the remote system, 'Global Contacts': active contacts that are known on the system. The fallback is meant for Redmatrix servers and older friendica servers, where global contacts weren't available. The fallback increases the server load, so the recommened setting is 'Users, Global Contacts'."), $poco_discovery_choices),
777                 '$poco_discovery_since' => array('poco_discovery_since', t("Timeframe for fetching global contacts"), (string) intval(get_config('system','poco_discovery_since')), t("When the discovery is activated, this value defines the timeframe for the activity of the global contacts that are fetched from other servers."), $poco_discovery_since_choices),
778                 '$poco_local_search'    => array('poco_local_search', t("Search the local directory"), get_config('system','poco_local_search'), t("Search the local directory instead of the global directory. When searching locally, every search will be executed on the global directory in the background. This improves the search results when the search is repeated.")),
779
780                 '$nodeinfo'             => array('nodeinfo', t("Publish server information"), get_config('system','nodeinfo'), t("If enabled, general server and usage data will be published. The data contains the name and version of the server, number of users with public profiles, number of posts and the activated protocols and connectors. See <a href='http://the-federation.info/'>the-federation.info</a> for details.")),
781
782                 '$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.")),
783                 '$suppress_language'    => array('suppress_language', t("Suppress Language"), get_config('system','suppress_language'), t("Suppress language information in meta information about a posting.")),
784                 '$suppress_tags'        => array('suppress_tags', t("Suppress Tags"), get_config('system','suppress_tags'), t("Suppress showing a list of hashtags at the end of the posting.")),
785                 '$itemcache'            => array('itemcache', t("Path to item cache"), get_config('system','itemcache'), t("The item caches buffers generated bbcode and external images.")),
786                 '$itemcache_duration'   => array('itemcache_duration', t("Cache duration in seconds"), get_config('system','itemcache_duration'), t("How long should the cache files be hold? Default value is 86400 seconds (One day). To disable the item cache, set the value to -1.")),
787                 '$max_comments'         => array('max_comments', t("Maximum numbers of comments per post"), get_config('system','max_comments'), t("How much comments should be shown for each post? Default value is 100.")),
788                 '$lockpath'             => array('lockpath', t("Path for lock file"), get_config('system','lockpath'), t("The lock file is used to avoid multiple pollers at one time. Only define a folder here.")),
789                 '$temppath'             => array('temppath', t("Temp path"), get_config('system','temppath'), t("If you have a restricted system where the webserver can't access the system temp path, enter another path here.")),
790                 '$basepath'             => array('basepath', t("Base path to installation"), get_config('system','basepath'), t("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.")),
791                 '$proxy_disabled'       => array('proxy_disabled', t("Disable picture proxy"), get_config('system','proxy_disabled'), t("The picture proxy increases performance and privacy. It shouldn't be used on systems with very low bandwith.")),
792                 '$old_pager'            => array('old_pager', t("Enable old style pager"), get_config('system','old_pager'), t("The old style pager has page numbers but slows down massively the page speed.")),
793                 '$only_tag_search'      => array('only_tag_search', t("Only search in tags"), get_config('system','only_tag_search'), t("On large systems the text search can slow down the system extremely.")),
794
795                 '$relocate_url'         => array('relocate_url', t("New base url"), $a->get_baseurl(), t("Change base url for this server. Sends relocate message to all DFRN contacts of all users.")),
796
797                 '$rino'                 => array('rino', t("RINO Encryption"), intval(get_config('system','rino_encrypt')), t("Encryption layer between nodes."), array("Disabled", "RINO1 (deprecated)", "RINO2")),
798                 '$embedly'              => array('embedly', t("Embedly API key"), get_config('system','embedly'), t("<a href='http://embed.ly'>Embedly</a> is used to fetch additional data for web pages. This is an optional parameter.")),
799
800                 '$form_security_token' => get_form_security_token("admin_site")
801
802         ));
803
804 }
805
806
807 function admin_page_dbsync(&$a) {
808
809         $o = '';
810
811         if($a->argc > 3 && intval($a->argv[3]) && $a->argv[2] === 'mark') {
812                 set_config('database', 'update_' . intval($a->argv[3]), 'success');
813                 $curr = get_config('system','build');
814                 if(intval($curr) == intval($a->argv[3]))
815                         set_config('system','build',intval($curr) + 1);
816                 info( t('Update has been marked successful') . EOL);
817                 goaway($a->get_baseurl(true) . '/admin/dbsync');
818         }
819
820         if(($a->argc > 2) AND (intval($a->argv[2]) OR ($a->argv[2] === 'check'))) {
821                 require_once("include/dbstructure.php");
822                 $retval = update_structure(false, true);
823                 if (!$retval) {
824                         $o .= sprintf(t("Database structure update %s was successfully applied."), DB_UPDATE_VERSION)."<br />";
825                         set_config('database', 'dbupdate_'.DB_UPDATE_VERSION, 'success');
826                 } else
827                         $o .= sprintf(t("Executing of database structure update %s failed with error: %s"),
828                                         DB_UPDATE_VERSION, $retval)."<br />";
829                 if ($a->argv[2] === 'check')
830                         return $o;
831         }
832
833         if ($a->argc > 2 && intval($a->argv[2])) {
834                 require_once('update.php');
835                 $func = 'update_' . intval($a->argv[2]);
836                 if(function_exists($func)) {
837                         $retval = $func();
838                         if($retval === UPDATE_FAILED) {
839                                 $o .= sprintf(t("Executing %s failed with error: %s"), $func, $retval);
840                         }
841                         elseif($retval === UPDATE_SUCCESS) {
842                                 $o .= sprintf(t('Update %s was successfully applied.', $func));
843                                 set_config('database',$func, 'success');
844                         }
845                         else
846                                 $o .= sprintf(t('Update %s did not return a status. Unknown if it succeeded.'), $func);
847                 } else {
848                         $o .= sprintf(t('There was no additional update function %s that needed to be called.'), $func)."<br />";
849                         set_config('database',$func, 'success');
850                 }
851                 return $o;
852         }
853
854         $failed = array();
855         $r = q("select k, v from config where `cat` = 'database' ");
856         if(count($r)) {
857                 foreach($r as $rr) {
858                         $upd = intval(substr($rr['k'],7));
859                         if($upd < 1139 || $rr['v'] === 'success')
860                                 continue;
861                         $failed[] = $upd;
862                 }
863         }
864         if(! count($failed)) {
865                 $o = replace_macros(get_markup_template('structure_check.tpl'),array(
866                         '$base' => $a->get_baseurl(true),
867                         '$banner' => t('No failed updates.'),
868                         '$check' => t('Check database structure'),
869                 ));
870         } else {
871                 $o = replace_macros(get_markup_template('failed_updates.tpl'),array(
872                         '$base' => $a->get_baseurl(true),
873                         '$banner' => t('Failed Updates'),
874                         '$desc' => t('This does not include updates prior to 1139, which did not return a status.'),
875                         '$mark' => t('Mark success (if update was manually applied)'),
876                         '$apply' => t('Attempt to execute this update step automatically'),
877                         '$failed' => $failed
878                 ));
879         }
880
881         return $o;
882
883 }
884
885 /**
886  * Users admin page
887  *
888  * @param App $a
889  */
890 function admin_page_users_post(&$a){
891         $pending = ( x($_POST, 'pending') ? $_POST['pending'] : Array() );
892         $users = ( x($_POST, 'user') ? $_POST['user'] : Array() );
893         $nu_name = ( x($_POST, 'new_user_name') ? $_POST['new_user_name'] : '');
894         $nu_nickname = ( x($_POST, 'new_user_nickname') ? $_POST['new_user_nickname'] : '');
895         $nu_email = ( x($_POST, 'new_user_email') ? $_POST['new_user_email'] : '');
896
897         check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
898
899         if (!($nu_name==="") && !($nu_email==="") && !($nu_nickname==="")) {
900                 require_once('include/user.php');
901
902                 $result = create_user( array('username'=>$nu_name, 'email'=>$nu_email, 'nickname'=>$nu_nickname, 'verified'=>1)  );
903                 if(! $result['success']) {
904                         notice($result['message']);
905                         return;
906                 }
907                 $nu = $result['user'];
908                 $preamble = deindent(t('
909                         Dear %1$s,
910                                 the administrator of %2$s has set up an account for you.'));
911                 $body = deindent(t('
912                         The login details are as follows:
913
914                         Site Location:  %1$s
915                         Login Name:             %2$s
916                         Password:               %3$s
917
918                         You may change your password from your account "Settings" page after logging
919                         in.
920
921                         Please take a few moments to review the other account settings on that page.
922
923                         You may also wish to add some basic information to your default profile
924                         (on the "Profiles" page) so that other people can easily find you.
925
926                         We recommend setting your full name, adding a profile photo,
927                         adding some profile "keywords" (very useful in making new friends) - and
928                         perhaps what country you live in; if you do not wish to be more specific
929                         than that.
930
931                         We fully respect your right to privacy, and none of these items are necessary.
932                         If you are new and do not know anybody here, they may help
933                         you to make some new and interesting friends.
934
935                         Thank you and welcome to %4$s.'));
936
937                 $preamble = sprintf($preamble, $nu['username'], $a->config['sitename']);
938                 $body = sprintf($body, $a->get_baseurl(), $nu['email'], $result['password'], $a->config['sitename']);
939
940                 notification(array(
941                         'type' => "SYSTEM_EMAIL",
942                         'to_email' => $nu['email'],
943                         'subject'=> sprintf( t('Registration details for %s'), $a->config['sitename']),
944                         'preamble'=> $preamble,
945                         'body' => $body));
946
947         }
948
949         if (x($_POST,'page_users_block')){
950                 foreach($users as $uid){
951                         q("UPDATE `user` SET `blocked`=1-`blocked` WHERE `uid`=%s",
952                                 intval( $uid )
953                         );
954                 }
955                 notice( sprintf( tt("%s user blocked/unblocked", "%s users blocked/unblocked", count($users)), count($users)) );
956         }
957         if (x($_POST,'page_users_delete')){
958                 require_once("include/Contact.php");
959                 foreach($users as $uid){
960                         user_remove($uid);
961                 }
962                 notice( sprintf( tt("%s user deleted", "%s users deleted", count($users)), count($users)) );
963         }
964
965         if (x($_POST,'page_users_approve')){
966                 require_once("mod/regmod.php");
967                 foreach($pending as $hash){
968                         user_allow($hash);
969                 }
970         }
971         if (x($_POST,'page_users_deny')){
972                 require_once("mod/regmod.php");
973                 foreach($pending as $hash){
974                         user_deny($hash);
975                 }
976         }
977         goaway($a->get_baseurl(true) . '/admin/users' );
978         return; // NOTREACHED
979 }
980
981 /**
982  * @param App $a
983  * @return string
984  */
985 function admin_page_users(&$a){
986         if ($a->argc>2) {
987                 $uid = $a->argv[3];
988                 $user = q("SELECT username, blocked FROM `user` WHERE `uid`=%d", intval($uid));
989                 if (count($user)==0){
990                         notice( 'User not found' . EOL);
991                         goaway($a->get_baseurl(true) . '/admin/users' );
992                         return ''; // NOTREACHED
993                 }
994                 switch($a->argv[2]){
995                         case "delete":{
996                                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
997                                 // delete user
998                                 require_once("include/Contact.php");
999                                 user_remove($uid);
1000
1001                                 notice( sprintf(t("User '%s' deleted"), $user[0]['username']) . EOL);
1002                         }; break;
1003                         case "block":{
1004                                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
1005                                 q("UPDATE `user` SET `blocked`=%d WHERE `uid`=%s",
1006                                         intval( 1-$user[0]['blocked'] ),
1007                                         intval( $uid )
1008                                 );
1009                                 notice( sprintf( ($user[0]['blocked']?t("User '%s' unblocked"):t("User '%s' blocked")) , $user[0]['username']) . EOL);
1010                         }; break;
1011                 }
1012                 goaway($a->get_baseurl(true) . '/admin/users' );
1013                 return ''; // NOTREACHED
1014
1015         }
1016
1017         /* get pending */
1018         $pending = q("SELECT `register`.*, `contact`.`name`, `user`.`email`
1019                                  FROM `register`
1020                                  LEFT JOIN `contact` ON `register`.`uid` = `contact`.`uid`
1021                                  LEFT JOIN `user` ON `register`.`uid` = `user`.`uid`;");
1022
1023
1024         /* get users */
1025
1026         $total = q("SELECT count(*) as total FROM `user` where 1");
1027         if(count($total)) {
1028                 $a->set_pager_total($total[0]['total']);
1029                 $a->set_pager_itemspage(100);
1030         }
1031
1032
1033         $users = q("SELECT `user` . * , `contact`.`name` , `contact`.`url` , `contact`.`micro`, `lastitem`.`lastitem_date`, `user`.`account_expired`
1034                                 FROM
1035                                         (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid`
1036                                         FROM `item`
1037                                         WHERE `item`.`type` = 'wall'
1038                                         GROUP BY `item`.`uid`) AS `lastitem`
1039                                                  RIGHT OUTER JOIN `user` ON `user`.`uid` = `lastitem`.`uid`,
1040                                            `contact`
1041                                 WHERE
1042                                            `user`.`uid` = `contact`.`uid`
1043                                                 AND `user`.`verified` =1
1044                                         AND `contact`.`self` =1
1045                                 ORDER BY `contact`.`name` LIMIT %d, %d
1046                                 ",
1047                                 intval($a->pager['start']),
1048                                 intval($a->pager['itemspage'])
1049                                 );
1050
1051         $adminlist = explode(",", str_replace(" ", "", $a->config['admin_email']));
1052         $_setup_users = function ($e) use ($adminlist){
1053                 $accounts = Array(
1054                         t('Normal Account'),
1055                         t('Soapbox Account'),
1056                         t('Community/Celebrity Account'),
1057                                                 t('Automatic Friend Account')
1058                 );
1059                 $e['page-flags'] = $accounts[$e['page-flags']];
1060                 $e['register_date'] = relative_date($e['register_date']);
1061                 $e['login_date'] = relative_date($e['login_date']);
1062                 $e['lastitem_date'] = relative_date($e['lastitem_date']);
1063                 //$e['is_admin'] = ($e['email'] === $a->config['admin_email']);
1064                 $e['is_admin'] = in_array($e['email'], $adminlist);
1065                 $e['is_deletable'] = (intval($e['uid']) != local_user());
1066                 $e['deleted'] = ($e['account_removed']?relative_date($e['account_expires_on']):False);
1067                 return $e;
1068         };
1069         $users = array_map($_setup_users, $users);
1070
1071
1072         // Get rid of dashes in key names, Smarty3 can't handle them
1073         // and extracting deleted users
1074
1075         $tmp_users = Array();
1076         $deleted = Array();
1077
1078         while(count($users)) {
1079                 $new_user = Array();
1080                 foreach( array_pop($users) as $k => $v) {
1081                         $k = str_replace('-','_',$k);
1082                         $new_user[$k] = $v;
1083                 }
1084                 if($new_user['deleted']) {
1085                         array_push($deleted, $new_user);
1086                 }
1087                 else {
1088                         array_push($tmp_users, $new_user);
1089                 }
1090         }
1091         //Reversing the two array, and moving $tmp_users to $users
1092         array_reverse($deleted);
1093         while(count($tmp_users)) {
1094                 array_push($users, array_pop($tmp_users));
1095         }
1096
1097         $t = get_markup_template("admin_users.tpl");
1098         $o = replace_macros($t, array(
1099                 // strings //
1100                 '$title' => t('Administration'),
1101                 '$page' => t('Users'),
1102                 '$submit' => t('Add User'),
1103                 '$select_all' => t('select all'),
1104                 '$h_pending' => t('User registrations waiting for confirm'),
1105                 '$h_deleted' => t('User waiting for permanent deletion'),
1106                 '$th_pending' => array( t('Request date'), t('Name'), t('Email') ),
1107                 '$no_pending' =>  t('No registrations.'),
1108                 '$approve' => t('Approve'),
1109                 '$deny' => t('Deny'),
1110                 '$delete' => t('Delete'),
1111                 '$block' => t('Block'),
1112                 '$unblock' => t('Unblock'),
1113                 '$siteadmin' => t('Site admin'),
1114                 '$accountexpired' => t('Account expired'),
1115
1116                 '$h_users' => t('Users'),
1117                 '$h_newuser' => t('New User'),
1118                 '$th_deleted' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'), t('Deleted since') ),
1119                 '$th_users' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'),  t('Account') ),
1120
1121                 '$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?'),
1122                 '$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?'),
1123
1124                 '$form_security_token' => get_form_security_token("admin_users"),
1125
1126                 // values //
1127                 '$baseurl' => $a->get_baseurl(true),
1128
1129                 '$pending' => $pending,
1130                 'deleted' => $deleted,
1131                 '$users' => $users,
1132                 '$newusername'  => array('new_user_name', t("Name"), '', t("Name of the new user.")),
1133                 '$newusernickname'  => array('new_user_nickname', t("Nickname"), '', t("Nickname of the new user.")),
1134                 '$newuseremail'  => array('new_user_email', t("Email"), '', t("Email address of the new user."), '', '', 'email'),
1135         ));
1136         $o .= paginate($a);
1137         return $o;
1138 }
1139
1140
1141 /**
1142  * Plugins admin page
1143  *
1144  * @param App $a
1145  * @return string
1146  */
1147 function admin_page_plugins(&$a){
1148
1149         /**
1150          * Single plugin
1151          */
1152         if ($a->argc == 3){
1153                 $plugin = $a->argv[2];
1154                 if (!is_file("addon/$plugin/$plugin.php")){
1155                         notice( t("Item not found.") );
1156                         return '';
1157                 }
1158
1159                 if (x($_GET,"a") && $_GET['a']=="t"){
1160                         check_form_security_token_redirectOnErr('/admin/plugins', 'admin_themes', 't');
1161
1162                         // Toggle plugin status
1163                         $idx = array_search($plugin, $a->plugins);
1164                         if ($idx !== false){
1165                                 unset($a->plugins[$idx]);
1166                                 uninstall_plugin($plugin);
1167                                 info( sprintf( t("Plugin %s disabled."), $plugin ) );
1168                         } else {
1169                                 $a->plugins[] = $plugin;
1170                                 install_plugin($plugin);
1171                                 info( sprintf( t("Plugin %s enabled."), $plugin ) );
1172                         }
1173                         set_config("system","addon", implode(", ",$a->plugins));
1174                         goaway($a->get_baseurl(true) . '/admin/plugins' );
1175                         return ''; // NOTREACHED
1176                 }
1177                 // display plugin details
1178                 require_once('library/markdown.php');
1179
1180                 if (in_array($plugin, $a->plugins)){
1181                         $status="on"; $action= t("Disable");
1182                 } else {
1183                         $status="off"; $action= t("Enable");
1184                 }
1185
1186                 $readme=Null;
1187                 if (is_file("addon/$plugin/README.md")){
1188                         $readme = file_get_contents("addon/$plugin/README.md");
1189                         $readme = Markdown($readme);
1190                 } else if (is_file("addon/$plugin/README")){
1191                         $readme = "<pre>". file_get_contents("addon/$plugin/README") ."</pre>";
1192                 }
1193
1194                 $admin_form="";
1195                 if (is_array($a->plugins_admin) && in_array($plugin, $a->plugins_admin)){
1196                         @require_once("addon/$plugin/$plugin.php");
1197                         $func = $plugin.'_plugin_admin';
1198                         $func($a, $admin_form);
1199                 }
1200
1201                 $t = get_markup_template("admin_plugins_details.tpl");
1202
1203                 return replace_macros($t, array(
1204                         '$title' => t('Administration'),
1205                         '$page' => t('Plugins'),
1206                         '$toggle' => t('Toggle'),
1207                         '$settings' => t('Settings'),
1208                         '$baseurl' => $a->get_baseurl(true),
1209
1210                         '$plugin' => $plugin,
1211                         '$status' => $status,
1212                         '$action' => $action,
1213                         '$info' => get_plugin_info($plugin),
1214                         '$str_author' => t('Author: '),
1215                         '$str_maintainer' => t('Maintainer: '),
1216
1217                         '$admin_form' => $admin_form,
1218                         '$function' => 'plugins',
1219                         '$screenshot' => '',
1220                         '$readme' => $readme,
1221
1222                         '$form_security_token' => get_form_security_token("admin_themes"),
1223                 ));
1224         }
1225
1226
1227
1228         /**
1229          * List plugins
1230          */
1231
1232         if (x($_GET,"a") && $_GET['a']=="r"){
1233                 check_form_security_token_redirectOnErr($a->get_baseurl().'/admin/plugins', 'admin_themes', 't');
1234                 reload_plugins();
1235                 info("Plugins reloaded");
1236                 goaway($a->get_baseurl().'/admin/plugins');
1237         }
1238
1239         $plugins = array();
1240         $files = glob("addon/*/"); /* */
1241         if($files) {
1242                 foreach($files as $file) {
1243                         if (is_dir($file)){
1244                                 list($tmp, $id)=array_map("trim", explode("/",$file));
1245                                 $info = get_plugin_info($id);
1246                                 $show_plugin = true;
1247
1248                                 // If the addon is unsupported, then only show it, when it is enabled
1249                                 if ((strtolower($info["status"]) == "unsupported") AND !in_array($id,  $a->plugins))
1250                                         $show_plugin = false;
1251
1252                                 // Override the above szenario, when the admin really wants to see outdated stuff
1253                                 if (get_config("system", "show_unsupported_addons"))
1254                                         $show_plugin = true;
1255
1256                                 if ($show_plugin)
1257                                         $plugins[] = array($id, (in_array($id,  $a->plugins)?"on":"off") , $info);
1258                         }
1259                 }
1260         }
1261
1262         $t = get_markup_template("admin_plugins.tpl");
1263         return replace_macros($t, array(
1264                 '$title' => t('Administration'),
1265                 '$page' => t('Plugins'),
1266                 '$submit' => t('Save Settings'),
1267                 '$reload' => t('Reload active plugins'),
1268                 '$baseurl' => $a->get_baseurl(true),
1269                 '$function' => 'plugins',
1270                 '$plugins' => $plugins,
1271                 '$form_security_token' => get_form_security_token("admin_themes"),
1272         ));
1273 }
1274
1275 /**
1276  * @param array $themes
1277  * @param string $th
1278  * @param int $result
1279  */
1280 function toggle_theme(&$themes,$th,&$result) {
1281         for($x = 0; $x < count($themes); $x ++) {
1282                 if($themes[$x]['name'] === $th) {
1283                         if($themes[$x]['allowed']) {
1284                                 $themes[$x]['allowed'] = 0;
1285                                 $result = 0;
1286                         }
1287                         else {
1288                                 $themes[$x]['allowed'] = 1;
1289                                 $result = 1;
1290                         }
1291                 }
1292         }
1293 }
1294
1295 /**
1296  * @param array $themes
1297  * @param string $th
1298  * @return int
1299  */
1300 function theme_status($themes,$th) {
1301         for($x = 0; $x < count($themes); $x ++) {
1302                 if($themes[$x]['name'] === $th) {
1303                         if($themes[$x]['allowed']) {
1304                                 return 1;
1305                         }
1306                         else {
1307                                 return 0;
1308                         }
1309                 }
1310         }
1311         return 0;
1312 }
1313
1314
1315 /**
1316  * @param array $themes
1317  * @return string
1318  */
1319 function rebuild_theme_table($themes) {
1320         $o = '';
1321         if(count($themes)) {
1322                 foreach($themes as $th) {
1323                         if($th['allowed']) {
1324                                 if(strlen($o))
1325                                         $o .= ',';
1326                                 $o .= $th['name'];
1327                         }
1328                 }
1329         }
1330         return $o;
1331 }
1332
1333
1334 /**
1335  * Themes admin page
1336  *
1337  * @param App $a
1338  * @return string
1339  */
1340 function admin_page_themes(&$a){
1341
1342         $allowed_themes_str = get_config('system','allowed_themes');
1343         $allowed_themes_raw = explode(',',$allowed_themes_str);
1344         $allowed_themes = array();
1345         if(count($allowed_themes_raw))
1346                 foreach($allowed_themes_raw as $x)
1347                         if(strlen(trim($x)))
1348                                 $allowed_themes[] = trim($x);
1349
1350         $themes = array();
1351         $files = glob('view/theme/*'); /* */
1352         if($files) {
1353                 foreach($files as $file) {
1354                         $f = basename($file);
1355                         $is_experimental = intval(file_exists($file . '/experimental'));
1356                         $is_supported = 1-(intval(file_exists($file . '/unsupported')));
1357                         $is_allowed = intval(in_array($f,$allowed_themes));
1358
1359                         if ($is_allowed OR $is_supported OR get_config("system", "show_unsupported_themes"))
1360                                 $themes[] = array('name' => $f, 'experimental' => $is_experimental, 'supported' => $is_supported, 'allowed' => $is_allowed);
1361                 }
1362         }
1363
1364         if(! count($themes)) {
1365                 notice( t('No themes found.'));
1366                 return '';
1367         }
1368
1369         /**
1370          * Single theme
1371          */
1372
1373         if ($a->argc == 3){
1374                 $theme = $a->argv[2];
1375                 if(! is_dir("view/theme/$theme")){
1376                         notice( t("Item not found.") );
1377                         return '';
1378                 }
1379
1380                 if (x($_GET,"a") && $_GET['a']=="t"){
1381                         check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't');
1382
1383                         // Toggle theme status
1384
1385                         toggle_theme($themes,$theme,$result);
1386                         $s = rebuild_theme_table($themes);
1387                         if($result) {
1388                                 install_theme($theme);
1389                                 info( sprintf('Theme %s enabled.',$theme));
1390                         }
1391                         else {
1392                                 uninstall_theme($theme);
1393                                 info( sprintf('Theme %s disabled.',$theme));
1394                         }
1395
1396                         set_config('system','allowed_themes',$s);
1397                         goaway($a->get_baseurl(true) . '/admin/themes' );
1398                         return ''; // NOTREACHED
1399                 }
1400
1401                 // display theme details
1402                 require_once('library/markdown.php');
1403
1404                 if (theme_status($themes,$theme)) {
1405                         $status="on"; $action= t("Disable");
1406                 } else {
1407                         $status="off"; $action= t("Enable");
1408                 }
1409
1410                 $readme=Null;
1411                 if (is_file("view/theme/$theme/README.md")){
1412                         $readme = file_get_contents("view/theme/$theme/README.md");
1413                         $readme = Markdown($readme);
1414                 } else if (is_file("view/theme/$theme/README")){
1415                         $readme = "<pre>". file_get_contents("view/theme/$theme/README") ."</pre>";
1416                 }
1417
1418                 $admin_form="";
1419                 if (is_file("view/theme/$theme/config.php")){
1420                         function __get_theme_admin_form(&$a, $theme) {
1421                                 $orig_theme = $a->theme;
1422                                 $orig_page = $a->page;
1423                                 $orig_session_theme = $_SESSION['theme'];
1424                                 require_once("view/theme/$theme/theme.php");
1425                                 require_once("view/theme/$theme/config.php");
1426                                 $_SESSION['theme'] = $theme;
1427
1428
1429                                 $init = $theme."_init";
1430                                 if(function_exists($init)) $init($a);
1431                                 if(function_exists("theme_admin")){
1432                                         $admin_form = theme_admin($a);
1433                                 }
1434
1435                                 $_SESSION['theme'] = $orig_session_theme;
1436                                 $a->theme = $orig_theme;
1437                                 $a->page = $orig_page;
1438                                 return $admin_form;
1439                         }
1440                         $admin_form = __get_theme_admin_form($a, $theme);
1441                 }
1442
1443                 $screenshot = array( get_theme_screenshot($theme), t('Screenshot'));
1444                 if(! stristr($screenshot[0],$theme))
1445                         $screenshot = null;
1446
1447                 $t = get_markup_template("admin_plugins_details.tpl");
1448                 return replace_macros($t, array(
1449                         '$title' => t('Administration'),
1450                         '$page' => t('Themes'),
1451                         '$toggle' => t('Toggle'),
1452                         '$settings' => t('Settings'),
1453                         '$baseurl' => $a->get_baseurl(true),
1454
1455                         '$plugin' => $theme,
1456                         '$status' => $status,
1457                         '$action' => $action,
1458                         '$info' => get_theme_info($theme),
1459                         '$function' => 'themes',
1460                         '$admin_form' => $admin_form,
1461                         '$str_author' => t('Author: '),
1462                         '$str_maintainer' => t('Maintainer: '),
1463                         '$screenshot' => $screenshot,
1464                         '$readme' => $readme,
1465
1466                         '$form_security_token' => get_form_security_token("admin_themes"),
1467                 ));
1468         }
1469
1470
1471         // reload active themes
1472         if (x($_GET,"a") && $_GET['a']=="r"){
1473                 check_form_security_token_redirectOnErr($a->get_baseurl().'/admin/themes', 'admin_themes', 't');
1474                 if ($themes) {
1475                         foreach($themes as $th) {
1476                                 if ($th['allowed']) {
1477                                         uninstall_theme($th['name']);
1478                                         install_theme($th['name']);
1479                                 }
1480                         }
1481                 }
1482                 info("Themes reloaded");
1483                 goaway($a->get_baseurl().'/admin/themes');
1484         }
1485
1486         /**
1487          * List themes
1488          */
1489
1490         $xthemes = array();
1491         if($themes) {
1492                 foreach($themes as $th) {
1493                         $xthemes[] = array($th['name'],(($th['allowed']) ? "on" : "off"), get_theme_info($th['name']));
1494                 }
1495         }
1496
1497
1498         $t = get_markup_template("admin_plugins.tpl");
1499         return replace_macros($t, array(
1500                 '$title' => t('Administration'),
1501                 '$page' => t('Themes'),
1502                 '$submit' => t('Save Settings'),
1503                 '$reload' => t('Reload active themes'),
1504                 '$baseurl' => $a->get_baseurl(true),
1505                 '$function' => 'themes',
1506                 '$plugins' => $xthemes,
1507                 '$experimental' => t('[Experimental]'),
1508                 '$unsupported' => t('[Unsupported]'),
1509                 '$form_security_token' => get_form_security_token("admin_themes"),
1510         ));
1511 }
1512
1513
1514 /**
1515  * Logs admin page
1516  *
1517  * @param App $a
1518  */
1519
1520 function admin_page_logs_post(&$a) {
1521         if (x($_POST,"page_logs")) {
1522                 check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
1523
1524                 $logfile                =       ((x($_POST,'logfile'))          ? notags(trim($_POST['logfile']))       : '');
1525                 $debugging              =       ((x($_POST,'debugging'))        ? true                                                          : false);
1526                 $loglevel               =       ((x($_POST,'loglevel'))         ? intval(trim($_POST['loglevel']))      : 0);
1527
1528                 set_config('system','logfile', $logfile);
1529                 set_config('system','debugging',  $debugging);
1530                 set_config('system','loglevel', $loglevel);
1531
1532
1533         }
1534
1535         info( t("Log settings updated.") );
1536         goaway($a->get_baseurl(true) . '/admin/logs' );
1537         return; // NOTREACHED
1538 }
1539
1540 /**
1541  * @param App $a
1542  * @return string
1543  */
1544 function admin_page_logs(&$a){
1545
1546         $log_choices = Array(
1547                 LOGGER_NORMAL => 'Normal',
1548                 LOGGER_TRACE => 'Trace',
1549                 LOGGER_DEBUG => 'Debug',
1550                 LOGGER_DATA => 'Data',
1551                 LOGGER_ALL => 'All'
1552         );
1553
1554         $t = get_markup_template("admin_logs.tpl");
1555
1556         $f = get_config('system','logfile');
1557
1558         $data = '';
1559
1560         if(!file_exists($f)) {
1561                 $data = t("Error trying to open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f exist and is
1562 readable.");
1563         }
1564         else {
1565                 $fp = fopen($f, 'r');
1566                 if(!$fp) {
1567                         $data = t("Couldn't open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f is readable.");
1568                 }
1569                 else {
1570                         $fstat = fstat($fp);
1571                         $size = $fstat['size'];
1572                         if($size != 0)
1573                         {
1574                                 if($size > 5000000 || $size < 0)
1575                                         $size = 5000000;
1576                                 $seek = fseek($fp,0-$size,SEEK_END);
1577                                 if($seek === 0) {
1578                                         $data = escape_tags(fread($fp,$size));
1579                                         while(! feof($fp))
1580                                                 $data .= escape_tags(fread($fp,4096));
1581                                 }
1582                         }
1583                         fclose($fp);
1584                 }
1585         }
1586
1587         return replace_macros($t, array(
1588                 '$title' => t('Administration'),
1589                 '$page' => t('Logs'),
1590                 '$submit' => t('Save Settings'),
1591                 '$clear' => t('Clear'),
1592                 '$data' => $data,
1593                 '$baseurl' => $a->get_baseurl(true),
1594                 '$logname' =>  get_config('system','logfile'),
1595
1596                                                                         // name, label, value, help string, extra data...
1597                 '$debugging'            => array('debugging', t("Enable Debugging"),get_config('system','debugging'), ""),
1598                 '$logfile'                      => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Friendica top-level directory.")),
1599                 '$loglevel'             => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices),
1600
1601                 '$form_security_token' => get_form_security_token("admin_logs"),
1602         ));
1603 }
1604
1605 /**
1606  * @param App $a
1607  */
1608 function admin_page_remoteupdate_post(&$a) {
1609         // this function should be called via ajax post
1610         if(!is_site_admin()) {
1611                 return;
1612         }
1613
1614
1615         if (x($_POST,'remotefile') && $_POST['remotefile']!=""){
1616                 $remotefile = $_POST['remotefile'];
1617                 $ftpdata = (x($_POST['ftphost'])?$_POST:false);
1618                 doUpdate($remotefile, $ftpdata);
1619         } else {
1620                 echo "No remote file to download. Abort!";
1621         }
1622
1623         killme();
1624 }
1625
1626 /**
1627  * @param App $a
1628  * @return string
1629  */
1630 function admin_page_remoteupdate(&$a) {
1631         if(!is_site_admin()) {
1632                 return login(false);
1633         }
1634
1635         $canwrite = canWeWrite();
1636         $canftp = function_exists('ftp_connect');
1637
1638         $needupdate = true;
1639         $u = checkUpdate();
1640         if (!is_array($u)){
1641                 $needupdate = false;
1642                 $u = array('','','');
1643         }
1644
1645         $tpl = get_markup_template("admin_remoteupdate.tpl");
1646         return replace_macros($tpl, array(
1647                 '$baseurl' => $a->get_baseurl(true),
1648                 '$submit' => t("Update now"),
1649                 '$close' => t("Close"),
1650                 '$localversion' => FRIENDICA_VERSION,
1651                 '$remoteversion' => $u[1],
1652                 '$needupdate' => $needupdate,
1653                 '$canwrite' => $canwrite,
1654                 '$canftp'       => $canftp,
1655                 '$ftphost'      => array('ftphost', t("FTP Host"), '',''),
1656                 '$ftppath'      => array('ftppath', t("FTP Path"), '/',''),
1657                 '$ftpuser'      => array('ftpuser', t("FTP User"), '',''),
1658                 '$ftppwd'       => array('ftppwd', t("FTP Password"), '',''),
1659                 '$remotefile'=>array('remotefile','', $u['2'],''),
1660         ));
1661
1662 }