]> git.mxchange.org Git - friendica.git/blob - mod/admin.php
Merge pull request #2156 from gerhard6380/develop
[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 ORDER BY `name`");
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         $optimize_max_tablesize =       ((x($_POST,'optimize_max_tablesize'))   ? intval(trim($_POST['optimize_max_tablesize'])): 100);
413         $poco_completion        =       ((x($_POST,'poco_completion'))          ? intval(trim($_POST['poco_completion']))       : false);
414         $poco_requery_days      =       ((x($_POST,'poco_requery_days'))        ? intval(trim($_POST['poco_requery_days']))     : 7);
415         $poco_discovery         =       ((x($_POST,'poco_discovery'))           ? intval(trim($_POST['poco_discovery']))        : 0);
416         $poco_discovery_since   =       ((x($_POST,'poco_discovery_since'))     ? intval(trim($_POST['poco_discovery_since']))  : 30);
417         $poco_local_search      =       ((x($_POST,'poco_local_search'))        ? intval(trim($_POST['poco_local_search']))     : false);
418         $nodeinfo               =       ((x($_POST,'nodeinfo'))                 ? intval(trim($_POST['nodeinfo']))              : false);
419         $dfrn_only              =       ((x($_POST,'dfrn_only'))                ? True                                          : False);
420         $ostatus_disabled       =       !((x($_POST,'ostatus_disabled'))        ? True                                          : False);
421         $ostatus_poll_interval  =       ((x($_POST,'ostatus_poll_interval'))    ? intval(trim($_POST['ostatus_poll_interval'])) :  0);
422         $diaspora_enabled       =       ((x($_POST,'diaspora_enabled'))         ? True                                          : False);
423         $ssl_policy             =       ((x($_POST,'ssl_policy'))               ? intval($_POST['ssl_policy'])                  : 0);
424         $force_ssl              =       ((x($_POST,'force_ssl'))                ? True                                          : False);
425         $old_share              =       ((x($_POST,'old_share'))                ? True                                          : False);
426         $hide_help              =       ((x($_POST,'hide_help'))                ? True                                          : False);
427         $suppress_language      =       ((x($_POST,'suppress_language'))        ? True                                          : False);
428         $suppress_tags          =       ((x($_POST,'suppress_tags'))            ? True                                          : False);
429         $use_fulltext_engine    =       ((x($_POST,'use_fulltext_engine'))      ? True                                          : False);
430         $itemcache              =       ((x($_POST,'itemcache'))                ? notags(trim($_POST['itemcache']))             : '');
431         $itemcache_duration     =       ((x($_POST,'itemcache_duration'))       ? intval($_POST['itemcache_duration'])          : 0);
432         $max_comments           =       ((x($_POST,'max_comments'))             ? intval($_POST['max_comments'])                : 0);
433         $lockpath               =       ((x($_POST,'lockpath'))                 ? notags(trim($_POST['lockpath']))              : '');
434         $temppath               =       ((x($_POST,'temppath'))                 ? notags(trim($_POST['temppath']))              : '');
435         $basepath               =       ((x($_POST,'basepath'))                 ? notags(trim($_POST['basepath']))              : '');
436         $singleuser             =       ((x($_POST,'singleuser'))               ? notags(trim($_POST['singleuser']))            : '');
437         $proxy_disabled         =       ((x($_POST,'proxy_disabled'))           ? True                                          : False);
438         $old_pager              =       ((x($_POST,'old_pager'))                ? True                                          : False);
439         $only_tag_search        =       ((x($_POST,'only_tag_search'))          ? True                                          : False);
440         $rino                   =       ((x($_POST,'rino'))                             ? intval($_POST['rino'])                                : 0);
441         $embedly                =       ((x($_POST,'embedly'))                  ? notags(trim($_POST['embedly']))               : '');
442
443         if ($a->get_path() != "")
444                 $diaspora_enabled = false;
445
446         if (!$thread_allow)
447                 $ostatus_disabled = true;
448
449         if($ssl_policy != intval(get_config('system','ssl_policy'))) {
450                 if($ssl_policy == SSL_POLICY_FULL) {
451                         q("update `contact` set
452                                 `url`     = replace(`url`    , 'http:' , 'https:'),
453                                 `photo`   = replace(`photo`  , 'http:' , 'https:'),
454                                 `thumb`   = replace(`thumb`  , 'http:' , 'https:'),
455                                 `micro`   = replace(`micro`  , 'http:' , 'https:'),
456                                 `request` = replace(`request`, 'http:' , 'https:'),
457                                 `notify`  = replace(`notify` , 'http:' , 'https:'),
458                                 `poll`    = replace(`poll`   , 'http:' , 'https:'),
459                                 `confirm` = replace(`confirm`, 'http:' , 'https:'),
460                                 `poco`    = replace(`poco`   , 'http:' , 'https:')
461                                 where `self` = 1"
462                         );
463                         q("update `profile` set
464                                 `photo`   = replace(`photo`  , 'http:' , 'https:'),
465                                 `thumb`   = replace(`thumb`  , 'http:' , 'https:')
466                                 where 1 "
467                         );
468                 }
469                 elseif($ssl_policy == SSL_POLICY_SELFSIGN) {
470                         q("update `contact` set
471                                 `url`     = replace(`url`    , 'https:' , 'http:'),
472                                 `photo`   = replace(`photo`  , 'https:' , 'http:'),
473                                 `thumb`   = replace(`thumb`  , 'https:' , 'http:'),
474                                 `micro`   = replace(`micro`  , 'https:' , 'http:'),
475                                 `request` = replace(`request`, 'https:' , 'http:'),
476                                 `notify`  = replace(`notify` , 'https:' , 'http:'),
477                                 `poll`    = replace(`poll`   , 'https:' , 'http:'),
478                                 `confirm` = replace(`confirm`, 'https:' , 'http:'),
479                                 `poco`    = replace(`poco`   , 'https:' , 'http:')
480                                 where `self` = 1"
481                         );
482                         q("update `profile` set
483                                 `photo`   = replace(`photo`  , 'https:' , 'http:'),
484                                 `thumb`   = replace(`thumb`  , 'https:' , 'http:')
485                                 where 1 "
486                         );
487                 }
488         }
489         set_config('system','ssl_policy',$ssl_policy);
490         set_config('system','delivery_interval',$delivery_interval);
491         set_config('system','poll_interval',$poll_interval);
492         set_config('system','maxloadavg',$maxloadavg);
493         set_config('system','maxloadavg_frontend',$maxloadavg_frontend);
494         set_config('system','optimize_max_tablesize',$optimize_max_tablesize);
495         set_config('system','poco_completion',$poco_completion);
496         set_config('system','poco_requery_days',$poco_requery_days);
497         set_config('system','poco_discovery',$poco_discovery);
498         set_config('system','poco_discovery_since',$poco_discovery_since);
499         set_config('system','poco_local_search',$poco_local_search);
500         set_config('system','nodeinfo',$nodeinfo);
501         set_config('config','sitename',$sitename);
502         set_config('config','hostname',$hostname);
503         set_config('config','sender_email', $sender_email);
504         set_config('system','suppress_language',$suppress_language);
505         set_config('system','suppress_tags',$suppress_tags);
506         set_config('system','shortcut_icon',$shortcut_icon);
507         set_config('system','touch_icon',$touch_icon);
508
509         if ($banner==""){
510                 // don't know why, but del_config doesn't work...
511                 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
512                         dbesc("system"),
513                         dbesc("banner")
514                 );
515         } else {
516                 set_config('system','banner', $banner);
517         }
518         if ($info=="") {
519                 del_config('config','info');
520         } else {
521                 set_config('config','info',$info);
522         }
523         set_config('system','language', $language);
524         set_config('system','theme', $theme);
525         if ( $theme_mobile === '---' ) {
526                 del_config('system','mobile-theme');
527         } else {
528                 set_config('system','mobile-theme', $theme_mobile);
529                 }
530                 if ( $singleuser === '---' ) {
531                         del_config('system','singleuser');
532                 } else {
533                         set_config('system','singleuser', $singleuser);
534                 }
535         set_config('system','maximagesize', $maximagesize);
536         set_config('system','max_image_length', $maximagelength);
537         set_config('system','jpeg_quality', $jpegimagequality);
538
539         set_config('config','register_policy', $register_policy);
540         set_config('system','max_daily_registrations', $daily_registrations);
541         set_config('system','account_abandon_days', $abandon_days);
542         set_config('config','register_text', $register_text);
543         set_config('system','allowed_sites', $allowed_sites);
544         set_config('system','allowed_email', $allowed_email);
545         set_config('system','block_public', $block_public);
546         set_config('system','publish_all', $force_publish);
547         set_config('system','directory', $global_directory);
548         set_config('system','thread_allow', $thread_allow);
549         set_config('system','newuser_private', $newuser_private);
550         set_config('system','enotify_no_content', $enotify_no_content);
551         set_config('system','disable_embedded', $disable_embedded);
552         set_config('system','allow_users_remote_self', $allow_users_remote_self);
553
554         set_config('system','block_extended_register', $no_multi_reg);
555         set_config('system','no_openid', $no_openid);
556         set_config('system','no_regfullname', $no_regfullname);
557         set_config('system','community_page_style', $community_page_style);
558         set_config('system','max_author_posts_community_page', $max_author_posts_community_page);
559         set_config('system','no_utf', $no_utf);
560         set_config('system','verifyssl', $verifyssl);
561         set_config('system','proxyuser', $proxyuser);
562         set_config('system','proxy', $proxy);
563         set_config('system','curl_timeout', $timeout);
564         set_config('system','dfrn_only', $dfrn_only);
565         set_config('system','ostatus_disabled', $ostatus_disabled);
566         set_config('system','ostatus_poll_interval', $ostatus_poll_interval);
567         set_config('system','diaspora_enabled', $diaspora_enabled);
568
569         set_config('config','private_addons', $private_addons);
570
571         set_config('system','force_ssl', $force_ssl);
572         set_config('system','old_share', $old_share);
573         set_config('system','hide_help', $hide_help);
574         set_config('system','use_fulltext_engine', $use_fulltext_engine);
575         set_config('system','itemcache', $itemcache);
576         set_config('system','itemcache_duration', $itemcache_duration);
577         set_config('system','max_comments', $max_comments);
578         set_config('system','lockpath', $lockpath);
579         set_config('system','temppath', $temppath);
580         set_config('system','basepath', $basepath);
581         set_config('system','proxy_disabled', $proxy_disabled);
582         set_config('system','old_pager', $old_pager);
583         set_config('system','only_tag_search', $only_tag_search);
584
585
586         if ($rino==2 and !function_exists('mcrypt_create_iv')){
587                 notice(t("RINO2 needs mcrypt php extension to work."));
588         } else {
589                 set_config('system','rino_encrypt', $rino);
590         }
591
592         set_config('system','embedly', $embedly);
593
594
595         info( t('Site settings updated.') . EOL);
596         goaway($a->get_baseurl(true) . '/admin/site' );
597         return; // NOTREACHED
598
599 }
600
601 /**
602  * @param  App $a
603  * @return string
604  */
605 function admin_page_site(&$a) {
606
607         /* Installed langs */
608         $lang_choices = get_avaiable_languages();
609
610         if (strlen(get_config('system','directory_submit_url')) AND
611                 !strlen(get_config('system','directory'))) {
612                 set_config('system','directory', dirname(get_config('system','directory_submit_url')));
613                 del_config('system','directory_submit_url');
614         }
615
616         /* Installed themes */
617         $theme_choices = array();
618         $theme_choices_mobile = array();
619         $theme_choices_mobile["---"] = t("No special theme for mobile devices");
620         $files = glob('view/theme/*'); /**/
621         if($files) {
622                 foreach($files as $file) {
623                         if (intval(file_exists($file . '/unsupported')))
624                                 continue;
625
626                         $f = basename($file);
627                         $theme_name = ((file_exists($file . '/experimental')) ?  sprintf("%s - \x28Experimental\x29", $f) : $f);
628                         if (file_exists($file . '/mobile')) {
629                                 $theme_choices_mobile[$f] = $theme_name;
630                         } else {
631                                 $theme_choices[$f] = $theme_name;
632                         }
633                 }
634         }
635
636         /* Community page style */
637         $community_page_style_choices = array(
638                 CP_NO_COMMUNITY_PAGE => t("No community page"),
639                 CP_USERS_ON_SERVER => t("Public postings from users of this site"),
640                 CP_GLOBAL_COMMUNITY => t("Global community page")
641                 );
642
643         /* OStatus conversation poll choices */
644         $ostatus_poll_choices = array(
645                 "-2" => t("Never"),
646                 "-1" => t("At post arrival"),
647                 "0" => t("Frequently"),
648                 "60" => t("Hourly"),
649                 "720" => t("Twice daily"),
650                 "1440" => t("Daily")
651                 );
652
653         $poco_discovery_choices = array(
654                 "0" => t("Disabled"),
655                 "1" => t("Users"),
656                 "2" => t("Users, Global Contacts"),
657                 "3" => t("Users, Global Contacts/fallback"),
658                 );
659
660         $poco_discovery_since_choices = array(
661                 "30" => t("One month"),
662                 "91" => t("Three months"),
663                 "182" => t("Half a year"),
664                 "365" => t("One year"),
665                 );
666
667         /* get user names to make the install a personal install of X */
668         $user_names = array();
669         $user_names['---'] = t('Multi user instance');
670         $users = q("SELECT username, nickname FROM `user`");
671         foreach ($users as $user) {
672                 $user_names[$user['nickname']] = $user['username'];
673         }
674
675         /* Banner */
676         $banner = get_config('system','banner');
677         if($banner == false)
678                 $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>';
679         $banner = htmlspecialchars($banner);
680         $info = get_config('config','info');
681         $info = htmlspecialchars($info);
682
683         // Automatically create temporary paths
684         get_temppath();
685         get_lockpath();
686         get_itemcachepath();
687
688         //echo "<pre>"; var_dump($lang_choices); die("</pre>");
689
690         /* Register policy */
691         $register_choices = Array(
692                 REGISTER_CLOSED => t("Closed"),
693                 REGISTER_APPROVE => t("Requires approval"),
694                 REGISTER_OPEN => t("Open")
695         );
696
697         $ssl_choices = array(
698                 SSL_POLICY_NONE => t("No SSL policy, links will track page SSL state"),
699                 SSL_POLICY_FULL => t("Force all links to use SSL"),
700                 SSL_POLICY_SELFSIGN => t("Self-signed certificate, use SSL for local links only (discouraged)")
701         );
702
703         if ($a->config['hostname'] == "")
704                 $a->config['hostname'] = $a->get_hostname();
705
706         $diaspora_able = ($a->get_path() == "");
707
708         $t = get_markup_template("admin_site.tpl");
709         return replace_macros($t, array(
710                 '$title' => t('Administration'),
711                 '$page' => t('Site'),
712                 '$submit' => t('Save Settings'),
713                 '$registration' => t('Registration'),
714                 '$upload' => t('File upload'),
715                 '$corporate' => t('Policies'),
716                 '$advanced' => t('Advanced'),
717                 '$portable_contacts' => t('Auto Discovered Contact Directory'),
718                 '$performance' => t('Performance'),
719                 '$relocate'=> t('Relocate - WARNING: advanced function. Could make this server unreachable.'),
720                 '$baseurl' => $a->get_baseurl(true),
721                 // name, label, value, help string, extra data...
722                 '$sitename'             => array('sitename', t("Site name"), $a->config['sitename'],''),
723                 '$hostname'             => array('hostname', t("Host name"), $a->config['hostname'], ""),
724                 '$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"),
725                 '$banner'               => array('banner', t("Banner/Logo"), $banner, ""),
726                 '$shortcut_icon'        => array('shortcut_icon', t("Shortcut icon"), get_config('system','shortcut_icon'),  t("Link to an icon that will be used for browsers.")),
727                 '$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.")),
728                 '$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())),
729                 '$language'             => array('language', t("System language"), get_config('system','language'), "", $lang_choices),
730                 '$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),
731                 '$theme_mobile'         => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile-theme'), t("Theme for mobile devices"), $theme_choices_mobile),
732                 '$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),
733                 '$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.")),
734                 '$old_share'            => array('old_share', t("Old style 'Share'"), get_config('system','old_share'), t("Deactivates the bbcode element 'share' for repeating items.")),
735                 '$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.")),
736                 '$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),
737                 '$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.")),
738                 '$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.")),
739                 '$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.")),
740
741                 '$register_policy'      => array('register_policy', t("Register policy"), $a->config['register_policy'], "", $register_choices),
742                 '$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.")),
743                 '$register_text'        => array('register_text', t("Register text"), $a->config['register_text'], t("Will be displayed prominently on the registration page.")),
744                 '$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.')),
745                 '$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")),
746                 '$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")),
747                 '$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.")),
748                 '$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.")),
749                 '$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.")),
750                 '$thread_allow'         => array('thread_allow', t("Allow threaded items"), get_config('system','thread_allow'), t("Allow infinite level threading for items on this site.")),
751                 '$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.")),
752                 '$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.")),
753                 '$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.")),
754                 '$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.")),
755                 '$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.')),
756                 '$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.")),
757                 '$no_openid'            => array('no_openid', t("OpenID support"), !get_config('system','no_openid'), t("OpenID support for registration and logins.")),
758                 '$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")),
759                 '$no_utf'               => array('no_utf', t("UTF-8 Regular expressions"), !get_config('system','no_utf'), t("Use PHP UTF8 regular expressions")),
760                 '$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),
761                 '$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')")),
762                 '$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.")),
763                 '$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),
764                 '$ostatus_not_able'     => t("OStatus support can only be enabled if threading is enabled."),
765                 '$diaspora_able'        => $diaspora_able,
766                 '$diaspora_not_able'    => t("Diaspora support can't be enabled because Friendica was installed into a sub directory."),
767                 '$diaspora_enabled'     => array('diaspora_enabled', t("Enable Diaspora support"), get_config('system','diaspora_enabled'), t("Provide built-in Diaspora network compatibility.")),
768                 '$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.")),
769                 '$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.")),
770                 '$proxyuser'            => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""),
771                 '$proxy'                => array('proxy', t("Proxy URL"), get_config('system','proxy'), ""),
772                 '$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).")),
773                 '$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.")),
774                 '$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.")),
775                 '$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.")),
776                 '$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.")),
777                 '$optimize_max_tablesize'=> array('optimize_max_tablesize', t("Maximum table size for optimization"), ((intval(get_config('system','optimize_max_tablesize')) > 0)?get_config('system','optimize_max_tablesize'):100), t("Maximum table size (in MB) for the automatic optimization - default 100 MB. Enter -1 to disable it.")),
778
779                 '$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.")),
780                 '$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.")),
781                 '$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),
782                 '$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),
783                 '$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.")),
784
785                 '$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.")),
786
787                 '$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.")),
788                 '$suppress_language'    => array('suppress_language', t("Suppress Language"), get_config('system','suppress_language'), t("Suppress language information in meta information about a posting.")),
789                 '$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.")),
790                 '$itemcache'            => array('itemcache', t("Path to item cache"), get_config('system','itemcache'), t("The item caches buffers generated bbcode and external images.")),
791                 '$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.")),
792                 '$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.")),
793                 '$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.")),
794                 '$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.")),
795                 '$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.")),
796                 '$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.")),
797                 '$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.")),
798                 '$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.")),
799
800                 '$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.")),
801
802                 '$rino'                 => array('rino', t("RINO Encryption"), intval(get_config('system','rino_encrypt')), t("Encryption layer between nodes."), array("Disabled", "RINO1 (deprecated)", "RINO2")),
803                 '$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.")),
804
805                 '$form_security_token' => get_form_security_token("admin_site")
806
807         ));
808
809 }
810
811
812 function admin_page_dbsync(&$a) {
813
814         $o = '';
815
816         if($a->argc > 3 && intval($a->argv[3]) && $a->argv[2] === 'mark') {
817                 set_config('database', 'update_' . intval($a->argv[3]), 'success');
818                 $curr = get_config('system','build');
819                 if(intval($curr) == intval($a->argv[3]))
820                         set_config('system','build',intval($curr) + 1);
821                 info( t('Update has been marked successful') . EOL);
822                 goaway($a->get_baseurl(true) . '/admin/dbsync');
823         }
824
825         if(($a->argc > 2) AND (intval($a->argv[2]) OR ($a->argv[2] === 'check'))) {
826                 require_once("include/dbstructure.php");
827                 $retval = update_structure(false, true);
828                 if (!$retval) {
829                         $o .= sprintf(t("Database structure update %s was successfully applied."), DB_UPDATE_VERSION)."<br />";
830                         set_config('database', 'dbupdate_'.DB_UPDATE_VERSION, 'success');
831                 } else
832                         $o .= sprintf(t("Executing of database structure update %s failed with error: %s"),
833                                         DB_UPDATE_VERSION, $retval)."<br />";
834                 if ($a->argv[2] === 'check')
835                         return $o;
836         }
837
838         if ($a->argc > 2 && intval($a->argv[2])) {
839                 require_once('update.php');
840                 $func = 'update_' . intval($a->argv[2]);
841                 if(function_exists($func)) {
842                         $retval = $func();
843                         if($retval === UPDATE_FAILED) {
844                                 $o .= sprintf(t("Executing %s failed with error: %s"), $func, $retval);
845                         }
846                         elseif($retval === UPDATE_SUCCESS) {
847                                 $o .= sprintf(t('Update %s was successfully applied.', $func));
848                                 set_config('database',$func, 'success');
849                         }
850                         else
851                                 $o .= sprintf(t('Update %s did not return a status. Unknown if it succeeded.'), $func);
852                 } else {
853                         $o .= sprintf(t('There was no additional update function %s that needed to be called.'), $func)."<br />";
854                         set_config('database',$func, 'success');
855                 }
856                 return $o;
857         }
858
859         $failed = array();
860         $r = q("select k, v from config where `cat` = 'database' ");
861         if(count($r)) {
862                 foreach($r as $rr) {
863                         $upd = intval(substr($rr['k'],7));
864                         if($upd < 1139 || $rr['v'] === 'success')
865                                 continue;
866                         $failed[] = $upd;
867                 }
868         }
869         if(! count($failed)) {
870                 $o = replace_macros(get_markup_template('structure_check.tpl'),array(
871                         '$base' => $a->get_baseurl(true),
872                         '$banner' => t('No failed updates.'),
873                         '$check' => t('Check database structure'),
874                 ));
875         } else {
876                 $o = replace_macros(get_markup_template('failed_updates.tpl'),array(
877                         '$base' => $a->get_baseurl(true),
878                         '$banner' => t('Failed Updates'),
879                         '$desc' => t('This does not include updates prior to 1139, which did not return a status.'),
880                         '$mark' => t('Mark success (if update was manually applied)'),
881                         '$apply' => t('Attempt to execute this update step automatically'),
882                         '$failed' => $failed
883                 ));
884         }
885
886         return $o;
887
888 }
889
890 /**
891  * Users admin page
892  *
893  * @param App $a
894  */
895 function admin_page_users_post(&$a){
896         $pending = ( x($_POST, 'pending') ? $_POST['pending'] : Array() );
897         $users = ( x($_POST, 'user') ? $_POST['user'] : Array() );
898         $nu_name = ( x($_POST, 'new_user_name') ? $_POST['new_user_name'] : '');
899         $nu_nickname = ( x($_POST, 'new_user_nickname') ? $_POST['new_user_nickname'] : '');
900         $nu_email = ( x($_POST, 'new_user_email') ? $_POST['new_user_email'] : '');
901
902         check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
903
904         if (!($nu_name==="") && !($nu_email==="") && !($nu_nickname==="")) {
905                 require_once('include/user.php');
906
907                 $result = create_user( array('username'=>$nu_name, 'email'=>$nu_email, 'nickname'=>$nu_nickname, 'verified'=>1)  );
908                 if(! $result['success']) {
909                         notice($result['message']);
910                         return;
911                 }
912                 $nu = $result['user'];
913                 $preamble = deindent(t('
914                         Dear %1$s,
915                                 the administrator of %2$s has set up an account for you.'));
916                 $body = deindent(t('
917                         The login details are as follows:
918
919                         Site Location:  %1$s
920                         Login Name:             %2$s
921                         Password:               %3$s
922
923                         You may change your password from your account "Settings" page after logging
924                         in.
925
926                         Please take a few moments to review the other account settings on that page.
927
928                         You may also wish to add some basic information to your default profile
929                         (on the "Profiles" page) so that other people can easily find you.
930
931                         We recommend setting your full name, adding a profile photo,
932                         adding some profile "keywords" (very useful in making new friends) - and
933                         perhaps what country you live in; if you do not wish to be more specific
934                         than that.
935
936                         We fully respect your right to privacy, and none of these items are necessary.
937                         If you are new and do not know anybody here, they may help
938                         you to make some new and interesting friends.
939
940                         Thank you and welcome to %4$s.'));
941
942                 $preamble = sprintf($preamble, $nu['username'], $a->config['sitename']);
943                 $body = sprintf($body, $a->get_baseurl(), $nu['email'], $result['password'], $a->config['sitename']);
944
945                 notification(array(
946                         'type' => "SYSTEM_EMAIL",
947                         'to_email' => $nu['email'],
948                         'subject'=> sprintf( t('Registration details for %s'), $a->config['sitename']),
949                         'preamble'=> $preamble,
950                         'body' => $body));
951
952         }
953
954         if (x($_POST,'page_users_block')){
955                 foreach($users as $uid){
956                         q("UPDATE `user` SET `blocked`=1-`blocked` WHERE `uid`=%s",
957                                 intval( $uid )
958                         );
959                 }
960                 notice( sprintf( tt("%s user blocked/unblocked", "%s users blocked/unblocked", count($users)), count($users)) );
961         }
962         if (x($_POST,'page_users_delete')){
963                 require_once("include/Contact.php");
964                 foreach($users as $uid){
965                         user_remove($uid);
966                 }
967                 notice( sprintf( tt("%s user deleted", "%s users deleted", count($users)), count($users)) );
968         }
969
970         if (x($_POST,'page_users_approve')){
971                 require_once("mod/regmod.php");
972                 foreach($pending as $hash){
973                         user_allow($hash);
974                 }
975         }
976         if (x($_POST,'page_users_deny')){
977                 require_once("mod/regmod.php");
978                 foreach($pending as $hash){
979                         user_deny($hash);
980                 }
981         }
982         goaway($a->get_baseurl(true) . '/admin/users' );
983         return; // NOTREACHED
984 }
985
986 /**
987  * @param App $a
988  * @return string
989  */
990 function admin_page_users(&$a){
991         if ($a->argc>2) {
992                 $uid = $a->argv[3];
993                 $user = q("SELECT username, blocked FROM `user` WHERE `uid`=%d", intval($uid));
994                 if (count($user)==0){
995                         notice( 'User not found' . EOL);
996                         goaway($a->get_baseurl(true) . '/admin/users' );
997                         return ''; // NOTREACHED
998                 }
999                 switch($a->argv[2]){
1000                         case "delete":{
1001                                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
1002                                 // delete user
1003                                 require_once("include/Contact.php");
1004                                 user_remove($uid);
1005
1006                                 notice( sprintf(t("User '%s' deleted"), $user[0]['username']) . EOL);
1007                         }; break;
1008                         case "block":{
1009                                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
1010                                 q("UPDATE `user` SET `blocked`=%d WHERE `uid`=%s",
1011                                         intval( 1-$user[0]['blocked'] ),
1012                                         intval( $uid )
1013                                 );
1014                                 notice( sprintf( ($user[0]['blocked']?t("User '%s' unblocked"):t("User '%s' blocked")) , $user[0]['username']) . EOL);
1015                         }; break;
1016                 }
1017                 goaway($a->get_baseurl(true) . '/admin/users' );
1018                 return ''; // NOTREACHED
1019
1020         }
1021
1022         /* get pending */
1023         $pending = q("SELECT `register`.*, `contact`.`name`, `user`.`email`
1024                                  FROM `register`
1025                                  LEFT JOIN `contact` ON `register`.`uid` = `contact`.`uid`
1026                                  LEFT JOIN `user` ON `register`.`uid` = `user`.`uid`;");
1027
1028
1029         /* get users */
1030
1031         $total = q("SELECT count(*) as total FROM `user` where 1");
1032         if(count($total)) {
1033                 $a->set_pager_total($total[0]['total']);
1034                 $a->set_pager_itemspage(100);
1035         }
1036
1037
1038         $users = q("SELECT `user` . * , `contact`.`name` , `contact`.`url` , `contact`.`micro`, `lastitem`.`lastitem_date`, `user`.`account_expired`
1039                                 FROM
1040                                         (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid`
1041                                         FROM `item`
1042                                         WHERE `item`.`type` = 'wall'
1043                                         GROUP BY `item`.`uid`) AS `lastitem`
1044                                                  RIGHT OUTER JOIN `user` ON `user`.`uid` = `lastitem`.`uid`,
1045                                            `contact`
1046                                 WHERE
1047                                            `user`.`uid` = `contact`.`uid`
1048                                                 AND `user`.`verified` =1
1049                                         AND `contact`.`self` =1
1050                                 ORDER BY `contact`.`name` LIMIT %d, %d
1051                                 ",
1052                                 intval($a->pager['start']),
1053                                 intval($a->pager['itemspage'])
1054                                 );
1055
1056         $adminlist = explode(",", str_replace(" ", "", $a->config['admin_email']));
1057         $_setup_users = function ($e) use ($adminlist){
1058                 $accounts = Array(
1059                         t('Normal Account'),
1060                         t('Soapbox Account'),
1061                         t('Community/Celebrity Account'),
1062                                                 t('Automatic Friend Account')
1063                 );
1064                 $e['page-flags'] = $accounts[$e['page-flags']];
1065                 $e['register_date'] = relative_date($e['register_date']);
1066                 $e['login_date'] = relative_date($e['login_date']);
1067                 $e['lastitem_date'] = relative_date($e['lastitem_date']);
1068                 //$e['is_admin'] = ($e['email'] === $a->config['admin_email']);
1069                 $e['is_admin'] = in_array($e['email'], $adminlist);
1070                 $e['is_deletable'] = (intval($e['uid']) != local_user());
1071                 $e['deleted'] = ($e['account_removed']?relative_date($e['account_expires_on']):False);
1072                 return $e;
1073         };
1074         $users = array_map($_setup_users, $users);
1075
1076
1077         // Get rid of dashes in key names, Smarty3 can't handle them
1078         // and extracting deleted users
1079
1080         $tmp_users = Array();
1081         $deleted = Array();
1082
1083         while(count($users)) {
1084                 $new_user = Array();
1085                 foreach( array_pop($users) as $k => $v) {
1086                         $k = str_replace('-','_',$k);
1087                         $new_user[$k] = $v;
1088                 }
1089                 if($new_user['deleted']) {
1090                         array_push($deleted, $new_user);
1091                 }
1092                 else {
1093                         array_push($tmp_users, $new_user);
1094                 }
1095         }
1096         //Reversing the two array, and moving $tmp_users to $users
1097         array_reverse($deleted);
1098         while(count($tmp_users)) {
1099                 array_push($users, array_pop($tmp_users));
1100         }
1101
1102         $t = get_markup_template("admin_users.tpl");
1103         $o = replace_macros($t, array(
1104                 // strings //
1105                 '$title' => t('Administration'),
1106                 '$page' => t('Users'),
1107                 '$submit' => t('Add User'),
1108                 '$select_all' => t('select all'),
1109                 '$h_pending' => t('User registrations waiting for confirm'),
1110                 '$h_deleted' => t('User waiting for permanent deletion'),
1111                 '$th_pending' => array( t('Request date'), t('Name'), t('Email') ),
1112                 '$no_pending' =>  t('No registrations.'),
1113                 '$approve' => t('Approve'),
1114                 '$deny' => t('Deny'),
1115                 '$delete' => t('Delete'),
1116                 '$block' => t('Block'),
1117                 '$unblock' => t('Unblock'),
1118                 '$siteadmin' => t('Site admin'),
1119                 '$accountexpired' => t('Account expired'),
1120
1121                 '$h_users' => t('Users'),
1122                 '$h_newuser' => t('New User'),
1123                 '$th_deleted' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'), t('Deleted since') ),
1124                 '$th_users' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'),  t('Account') ),
1125
1126                 '$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?'),
1127                 '$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?'),
1128
1129                 '$form_security_token' => get_form_security_token("admin_users"),
1130
1131                 // values //
1132                 '$baseurl' => $a->get_baseurl(true),
1133
1134                 '$pending' => $pending,
1135                 'deleted' => $deleted,
1136                 '$users' => $users,
1137                 '$newusername'  => array('new_user_name', t("Name"), '', t("Name of the new user.")),
1138                 '$newusernickname'  => array('new_user_nickname', t("Nickname"), '', t("Nickname of the new user.")),
1139                 '$newuseremail'  => array('new_user_email', t("Email"), '', t("Email address of the new user."), '', '', 'email'),
1140         ));
1141         $o .= paginate($a);
1142         return $o;
1143 }
1144
1145
1146 /**
1147  * Plugins admin page
1148  *
1149  * @param App $a
1150  * @return string
1151  */
1152 function admin_page_plugins(&$a){
1153
1154         /**
1155          * Single plugin
1156          */
1157         if ($a->argc == 3){
1158                 $plugin = $a->argv[2];
1159                 if (!is_file("addon/$plugin/$plugin.php")){
1160                         notice( t("Item not found.") );
1161                         return '';
1162                 }
1163
1164                 if (x($_GET,"a") && $_GET['a']=="t"){
1165                         check_form_security_token_redirectOnErr('/admin/plugins', 'admin_themes', 't');
1166
1167                         // Toggle plugin status
1168                         $idx = array_search($plugin, $a->plugins);
1169                         if ($idx !== false){
1170                                 unset($a->plugins[$idx]);
1171                                 uninstall_plugin($plugin);
1172                                 info( sprintf( t("Plugin %s disabled."), $plugin ) );
1173                         } else {
1174                                 $a->plugins[] = $plugin;
1175                                 install_plugin($plugin);
1176                                 info( sprintf( t("Plugin %s enabled."), $plugin ) );
1177                         }
1178                         set_config("system","addon", implode(", ",$a->plugins));
1179                         goaway($a->get_baseurl(true) . '/admin/plugins' );
1180                         return ''; // NOTREACHED
1181                 }
1182                 // display plugin details
1183                 require_once('library/markdown.php');
1184
1185                 if (in_array($plugin, $a->plugins)){
1186                         $status="on"; $action= t("Disable");
1187                 } else {
1188                         $status="off"; $action= t("Enable");
1189                 }
1190
1191                 $readme=Null;
1192                 if (is_file("addon/$plugin/README.md")){
1193                         $readme = file_get_contents("addon/$plugin/README.md");
1194                         $readme = Markdown($readme);
1195                 } else if (is_file("addon/$plugin/README")){
1196                         $readme = "<pre>". file_get_contents("addon/$plugin/README") ."</pre>";
1197                 }
1198
1199                 $admin_form="";
1200                 if (is_array($a->plugins_admin) && in_array($plugin, $a->plugins_admin)){
1201                         @require_once("addon/$plugin/$plugin.php");
1202                         $func = $plugin.'_plugin_admin';
1203                         $func($a, $admin_form);
1204                 }
1205
1206                 $t = get_markup_template("admin_plugins_details.tpl");
1207
1208                 return replace_macros($t, array(
1209                         '$title' => t('Administration'),
1210                         '$page' => t('Plugins'),
1211                         '$toggle' => t('Toggle'),
1212                         '$settings' => t('Settings'),
1213                         '$baseurl' => $a->get_baseurl(true),
1214
1215                         '$plugin' => $plugin,
1216                         '$status' => $status,
1217                         '$action' => $action,
1218                         '$info' => get_plugin_info($plugin),
1219                         '$str_author' => t('Author: '),
1220                         '$str_maintainer' => t('Maintainer: '),
1221
1222                         '$admin_form' => $admin_form,
1223                         '$function' => 'plugins',
1224                         '$screenshot' => '',
1225                         '$readme' => $readme,
1226
1227                         '$form_security_token' => get_form_security_token("admin_themes"),
1228                 ));
1229         }
1230
1231
1232
1233         /**
1234          * List plugins
1235          */
1236
1237         if (x($_GET,"a") && $_GET['a']=="r"){
1238                 check_form_security_token_redirectOnErr($a->get_baseurl().'/admin/plugins', 'admin_themes', 't');
1239                 reload_plugins();
1240                 info("Plugins reloaded");
1241                 goaway($a->get_baseurl().'/admin/plugins');
1242         }
1243
1244         $plugins = array();
1245         $files = glob("addon/*/"); /* */
1246         if($files) {
1247                 foreach($files as $file) {
1248                         if (is_dir($file)){
1249                                 list($tmp, $id)=array_map("trim", explode("/",$file));
1250                                 $info = get_plugin_info($id);
1251                                 $show_plugin = true;
1252
1253                                 // If the addon is unsupported, then only show it, when it is enabled
1254                                 if ((strtolower($info["status"]) == "unsupported") AND !in_array($id,  $a->plugins))
1255                                         $show_plugin = false;
1256
1257                                 // Override the above szenario, when the admin really wants to see outdated stuff
1258                                 if (get_config("system", "show_unsupported_addons"))
1259                                         $show_plugin = true;
1260
1261                                 if ($show_plugin)
1262                                         $plugins[] = array($id, (in_array($id,  $a->plugins)?"on":"off") , $info);
1263                         }
1264                 }
1265         }
1266
1267         $t = get_markup_template("admin_plugins.tpl");
1268         return replace_macros($t, array(
1269                 '$title' => t('Administration'),
1270                 '$page' => t('Plugins'),
1271                 '$submit' => t('Save Settings'),
1272                 '$reload' => t('Reload active plugins'),
1273                 '$baseurl' => $a->get_baseurl(true),
1274                 '$function' => 'plugins',
1275                 '$plugins' => $plugins,
1276                 '$form_security_token' => get_form_security_token("admin_themes"),
1277         ));
1278 }
1279
1280 /**
1281  * @param array $themes
1282  * @param string $th
1283  * @param int $result
1284  */
1285 function toggle_theme(&$themes,$th,&$result) {
1286         for($x = 0; $x < count($themes); $x ++) {
1287                 if($themes[$x]['name'] === $th) {
1288                         if($themes[$x]['allowed']) {
1289                                 $themes[$x]['allowed'] = 0;
1290                                 $result = 0;
1291                         }
1292                         else {
1293                                 $themes[$x]['allowed'] = 1;
1294                                 $result = 1;
1295                         }
1296                 }
1297         }
1298 }
1299
1300 /**
1301  * @param array $themes
1302  * @param string $th
1303  * @return int
1304  */
1305 function theme_status($themes,$th) {
1306         for($x = 0; $x < count($themes); $x ++) {
1307                 if($themes[$x]['name'] === $th) {
1308                         if($themes[$x]['allowed']) {
1309                                 return 1;
1310                         }
1311                         else {
1312                                 return 0;
1313                         }
1314                 }
1315         }
1316         return 0;
1317 }
1318
1319
1320 /**
1321  * @param array $themes
1322  * @return string
1323  */
1324 function rebuild_theme_table($themes) {
1325         $o = '';
1326         if(count($themes)) {
1327                 foreach($themes as $th) {
1328                         if($th['allowed']) {
1329                                 if(strlen($o))
1330                                         $o .= ',';
1331                                 $o .= $th['name'];
1332                         }
1333                 }
1334         }
1335         return $o;
1336 }
1337
1338
1339 /**
1340  * Themes admin page
1341  *
1342  * @param App $a
1343  * @return string
1344  */
1345 function admin_page_themes(&$a){
1346
1347         $allowed_themes_str = get_config('system','allowed_themes');
1348         $allowed_themes_raw = explode(',',$allowed_themes_str);
1349         $allowed_themes = array();
1350         if(count($allowed_themes_raw))
1351                 foreach($allowed_themes_raw as $x)
1352                         if(strlen(trim($x)))
1353                                 $allowed_themes[] = trim($x);
1354
1355         $themes = array();
1356         $files = glob('view/theme/*'); /* */
1357         if($files) {
1358                 foreach($files as $file) {
1359                         $f = basename($file);
1360                         $is_experimental = intval(file_exists($file . '/experimental'));
1361                         $is_supported = 1-(intval(file_exists($file . '/unsupported')));
1362                         $is_allowed = intval(in_array($f,$allowed_themes));
1363
1364                         if ($is_allowed OR $is_supported OR get_config("system", "show_unsupported_themes"))
1365                                 $themes[] = array('name' => $f, 'experimental' => $is_experimental, 'supported' => $is_supported, 'allowed' => $is_allowed);
1366                 }
1367         }
1368
1369         if(! count($themes)) {
1370                 notice( t('No themes found.'));
1371                 return '';
1372         }
1373
1374         /**
1375          * Single theme
1376          */
1377
1378         if ($a->argc == 3){
1379                 $theme = $a->argv[2];
1380                 if(! is_dir("view/theme/$theme")){
1381                         notice( t("Item not found.") );
1382                         return '';
1383                 }
1384
1385                 if (x($_GET,"a") && $_GET['a']=="t"){
1386                         check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't');
1387
1388                         // Toggle theme status
1389
1390                         toggle_theme($themes,$theme,$result);
1391                         $s = rebuild_theme_table($themes);
1392                         if($result) {
1393                                 install_theme($theme);
1394                                 info( sprintf('Theme %s enabled.',$theme));
1395                         }
1396                         else {
1397                                 uninstall_theme($theme);
1398                                 info( sprintf('Theme %s disabled.',$theme));
1399                         }
1400
1401                         set_config('system','allowed_themes',$s);
1402                         goaway($a->get_baseurl(true) . '/admin/themes' );
1403                         return ''; // NOTREACHED
1404                 }
1405
1406                 // display theme details
1407                 require_once('library/markdown.php');
1408
1409                 if (theme_status($themes,$theme)) {
1410                         $status="on"; $action= t("Disable");
1411                 } else {
1412                         $status="off"; $action= t("Enable");
1413                 }
1414
1415                 $readme=Null;
1416                 if (is_file("view/theme/$theme/README.md")){
1417                         $readme = file_get_contents("view/theme/$theme/README.md");
1418                         $readme = Markdown($readme);
1419                 } else if (is_file("view/theme/$theme/README")){
1420                         $readme = "<pre>". file_get_contents("view/theme/$theme/README") ."</pre>";
1421                 }
1422
1423                 $admin_form="";
1424                 if (is_file("view/theme/$theme/config.php")){
1425                         function __get_theme_admin_form(&$a, $theme) {
1426                                 $orig_theme = $a->theme;
1427                                 $orig_page = $a->page;
1428                                 $orig_session_theme = $_SESSION['theme'];
1429                                 require_once("view/theme/$theme/theme.php");
1430                                 require_once("view/theme/$theme/config.php");
1431                                 $_SESSION['theme'] = $theme;
1432
1433
1434                                 $init = $theme."_init";
1435                                 if(function_exists($init)) $init($a);
1436                                 if(function_exists("theme_admin")){
1437                                         $admin_form = theme_admin($a);
1438                                 }
1439
1440                                 $_SESSION['theme'] = $orig_session_theme;
1441                                 $a->theme = $orig_theme;
1442                                 $a->page = $orig_page;
1443                                 return $admin_form;
1444                         }
1445                         $admin_form = __get_theme_admin_form($a, $theme);
1446                 }
1447
1448                 $screenshot = array( get_theme_screenshot($theme), t('Screenshot'));
1449                 if(! stristr($screenshot[0],$theme))
1450                         $screenshot = null;
1451
1452                 $t = get_markup_template("admin_plugins_details.tpl");
1453                 return replace_macros($t, array(
1454                         '$title' => t('Administration'),
1455                         '$page' => t('Themes'),
1456                         '$toggle' => t('Toggle'),
1457                         '$settings' => t('Settings'),
1458                         '$baseurl' => $a->get_baseurl(true),
1459
1460                         '$plugin' => $theme,
1461                         '$status' => $status,
1462                         '$action' => $action,
1463                         '$info' => get_theme_info($theme),
1464                         '$function' => 'themes',
1465                         '$admin_form' => $admin_form,
1466                         '$str_author' => t('Author: '),
1467                         '$str_maintainer' => t('Maintainer: '),
1468                         '$screenshot' => $screenshot,
1469                         '$readme' => $readme,
1470
1471                         '$form_security_token' => get_form_security_token("admin_themes"),
1472                 ));
1473         }
1474
1475
1476         // reload active themes
1477         if (x($_GET,"a") && $_GET['a']=="r"){
1478                 check_form_security_token_redirectOnErr($a->get_baseurl().'/admin/themes', 'admin_themes', 't');
1479                 if ($themes) {
1480                         foreach($themes as $th) {
1481                                 if ($th['allowed']) {
1482                                         uninstall_theme($th['name']);
1483                                         install_theme($th['name']);
1484                                 }
1485                         }
1486                 }
1487                 info("Themes reloaded");
1488                 goaway($a->get_baseurl().'/admin/themes');
1489         }
1490
1491         /**
1492          * List themes
1493          */
1494
1495         $xthemes = array();
1496         if($themes) {
1497                 foreach($themes as $th) {
1498                         $xthemes[] = array($th['name'],(($th['allowed']) ? "on" : "off"), get_theme_info($th['name']));
1499                 }
1500         }
1501
1502
1503         $t = get_markup_template("admin_plugins.tpl");
1504         return replace_macros($t, array(
1505                 '$title' => t('Administration'),
1506                 '$page' => t('Themes'),
1507                 '$submit' => t('Save Settings'),
1508                 '$reload' => t('Reload active themes'),
1509                 '$baseurl' => $a->get_baseurl(true),
1510                 '$function' => 'themes',
1511                 '$plugins' => $xthemes,
1512                 '$experimental' => t('[Experimental]'),
1513                 '$unsupported' => t('[Unsupported]'),
1514                 '$form_security_token' => get_form_security_token("admin_themes"),
1515         ));
1516 }
1517
1518
1519 /**
1520  * Logs admin page
1521  *
1522  * @param App $a
1523  */
1524
1525 function admin_page_logs_post(&$a) {
1526         if (x($_POST,"page_logs")) {
1527                 check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
1528
1529                 $logfile                =       ((x($_POST,'logfile'))          ? notags(trim($_POST['logfile']))       : '');
1530                 $debugging              =       ((x($_POST,'debugging'))        ? true                                                          : false);
1531                 $loglevel               =       ((x($_POST,'loglevel'))         ? intval(trim($_POST['loglevel']))      : 0);
1532
1533                 set_config('system','logfile', $logfile);
1534                 set_config('system','debugging',  $debugging);
1535                 set_config('system','loglevel', $loglevel);
1536
1537
1538         }
1539
1540         info( t("Log settings updated.") );
1541         goaway($a->get_baseurl(true) . '/admin/logs' );
1542         return; // NOTREACHED
1543 }
1544
1545 /**
1546  * @param App $a
1547  * @return string
1548  */
1549 function admin_page_logs(&$a){
1550
1551         $log_choices = Array(
1552                 LOGGER_NORMAL => 'Normal',
1553                 LOGGER_TRACE => 'Trace',
1554                 LOGGER_DEBUG => 'Debug',
1555                 LOGGER_DATA => 'Data',
1556                 LOGGER_ALL => 'All'
1557         );
1558
1559         $t = get_markup_template("admin_logs.tpl");
1560
1561         $f = get_config('system','logfile');
1562
1563         $data = '';
1564
1565         if(!file_exists($f)) {
1566                 $data = t("Error trying to open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f exist and is
1567 readable.");
1568         }
1569         else {
1570                 $fp = fopen($f, 'r');
1571                 if(!$fp) {
1572                         $data = t("Couldn't open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f is readable.");
1573                 }
1574                 else {
1575                         $fstat = fstat($fp);
1576                         $size = $fstat['size'];
1577                         if($size != 0)
1578                         {
1579                                 if($size > 5000000 || $size < 0)
1580                                         $size = 5000000;
1581                                 $seek = fseek($fp,0-$size,SEEK_END);
1582                                 if($seek === 0) {
1583                                         $data = escape_tags(fread($fp,$size));
1584                                         while(! feof($fp))
1585                                                 $data .= escape_tags(fread($fp,4096));
1586                                 }
1587                         }
1588                         fclose($fp);
1589                 }
1590         }
1591
1592         return replace_macros($t, array(
1593                 '$title' => t('Administration'),
1594                 '$page' => t('Logs'),
1595                 '$submit' => t('Save Settings'),
1596                 '$clear' => t('Clear'),
1597                 '$data' => $data,
1598                 '$baseurl' => $a->get_baseurl(true),
1599                 '$logname' =>  get_config('system','logfile'),
1600
1601                                                                         // name, label, value, help string, extra data...
1602                 '$debugging'            => array('debugging', t("Enable Debugging"),get_config('system','debugging'), ""),
1603                 '$logfile'                      => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Friendica top-level directory.")),
1604                 '$loglevel'             => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices),
1605
1606                 '$form_security_token' => get_form_security_token("admin_logs"),
1607         ));
1608 }
1609
1610 /**
1611  * @param App $a
1612  */
1613 function admin_page_remoteupdate_post(&$a) {
1614         // this function should be called via ajax post
1615         if(!is_site_admin()) {
1616                 return;
1617         }
1618
1619
1620         if (x($_POST,'remotefile') && $_POST['remotefile']!=""){
1621                 $remotefile = $_POST['remotefile'];
1622                 $ftpdata = (x($_POST['ftphost'])?$_POST:false);
1623                 doUpdate($remotefile, $ftpdata);
1624         } else {
1625                 echo "No remote file to download. Abort!";
1626         }
1627
1628         killme();
1629 }
1630
1631 /**
1632  * @param App $a
1633  * @return string
1634  */
1635 function admin_page_remoteupdate(&$a) {
1636         if(!is_site_admin()) {
1637                 return login(false);
1638         }
1639
1640         $canwrite = canWeWrite();
1641         $canftp = function_exists('ftp_connect');
1642
1643         $needupdate = true;
1644         $u = checkUpdate();
1645         if (!is_array($u)){
1646                 $needupdate = false;
1647                 $u = array('','','');
1648         }
1649
1650         $tpl = get_markup_template("admin_remoteupdate.tpl");
1651         return replace_macros($tpl, array(
1652                 '$baseurl' => $a->get_baseurl(true),
1653                 '$submit' => t("Update now"),
1654                 '$close' => t("Close"),
1655                 '$localversion' => FRIENDICA_VERSION,
1656                 '$remoteversion' => $u[1],
1657                 '$needupdate' => $needupdate,
1658                 '$canwrite' => $canwrite,
1659                 '$canftp'       => $canftp,
1660                 '$ftphost'      => array('ftphost', t("FTP Host"), '',''),
1661                 '$ftppath'      => array('ftppath', t("FTP Path"), '/',''),
1662                 '$ftpuser'      => array('ftpuser', t("FTP User"), '',''),
1663                 '$ftppwd'       => array('ftppwd', t("FTP Password"), '',''),
1664                 '$remotefile'=>array('remotefile','', $u['2'],''),
1665         ));
1666
1667 }