Changeset 1315:220e119ae6c8
- Timestamp:
- 08/09/13 08:01:31 (10 years ago)
- Branch:
- twig
- Parents:
- 1158:9d7267aec27b (diff), 1314:99a1319b79fc (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent. - Files:
-
- 1 deleted
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
admin/auth.php
r1310 r1315 4 4 # This file is part of Dotclear 2. 5 5 # 6 # Copyright (c) 2003-201 3Olivier Meunier & Association Dotclear6 # Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 14 14 15 15 # If we have a session cookie, go to index.php 16 if (isset($_SESSION['sess_user_id'])) 17 { 16 if (isset($_SESSION['sess_user_id'])) { 18 17 http::redirect('index.php'); 19 18 } … … 23 22 $dlang = http::getAcceptLanguage(); 24 23 $dlang = ($dlang == '' ? 'en' : $dlang); 25 if ($dlang != 'en' && preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$dlang)) 26 { 24 if ($dlang != 'en' && preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$dlang)) { 27 25 l10n::set(dirname(__FILE__).'/../locales/'.$dlang.'/main'); 28 26 } 29 30 $page_url = http::getHost().$_SERVER['REQUEST_URI'];31 32 $change_pwd = $core->auth->allowPassChange() && isset($_POST['new_pwd']) && isset($_POST['new_pwd_c']) && isset($_POST['login_data']);33 $login_data = !empty($_POST['login_data']) ? html::escapeHTML($_POST['login_data']) : null;34 $recover = $core->auth->allowPassChange() && !empty($_REQUEST['recover']);35 $safe_mode = !empty($_REQUEST['safe_mode']);36 $akey = $core->auth->allowPassChange() && !empty($_GET['akey']) ? $_GET['akey'] : null;37 $user_id = $user_pwd = $user_key = $user_email = null;38 $err = $msg = null;39 27 40 28 # Auto upgrade … … 43 31 try { 44 32 if (($changes = dotclearUpgrade($core)) !== false) { 45 $msg = __('Dotclear has been upgraded.').'<!-- '.$changes.' -->'; 46 } 47 } catch (Exception $e) { 48 $err = $e->getMessage(); 49 } 50 } 51 52 # If we have POST login informations, go throug auth process 53 if (!empty($_POST['user_id']) && !empty($_POST['user_pwd'])) 33 $_ctx->setAlert(__('Dotclear has been upgraded.').'<!-- '.$changes.' -->'); 34 } 35 } 36 catch (Exception $e) { 37 $_ctx->addError($e->getMessage()); 38 } 39 } 40 41 /** 42 Actions for authentication on admin pages 43 */ 44 class adminPageAuth 54 45 { 55 $user_id = !empty($_POST['user_id']) ? $_POST['user_id'] : null; 56 $user_pwd = !empty($_POST['user_pwd']) ? $_POST['user_pwd'] : null; 57 } 58 # If we have COOKIE login informations, go throug auth process 59 elseif (isset($_COOKIE['dc_admin']) && strlen($_COOKIE['dc_admin']) == 104) 60 { 46 # Send new password from recover email 47 public static function send($akey) 48 { 49 global $core, $_ctx; 50 51 $_ctx->akey = true; 52 53 try { 54 $recover_res = $core->auth->recoverUserPassword($akey); 55 56 $subject = mb_encode_mimeheader('DotClear '.__('Your new password'),'UTF-8','B'); 57 $message = 58 __('Username:').' '.$recover_res['user_id']."\n". 59 __('Password:').' '.$recover_res['new_pass']."\n\n". 60 preg_replace('/\?(.*)$/','',http::getHost().$_SERVER['REQUEST_URI']); 61 62 $headers[] = 'From: dotclear@'.$_SERVER['HTTP_HOST']; 63 $headers[] = 'Content-Type: text/plain; charset=UTF-8;'; 64 65 mail::sendMail($recover_res['user_email'],$subject,$message,$headers); 66 $_ctx->setAlert(__('Your new password is in your mailbox.')); 67 } 68 catch (Exception $e) { 69 $_ctx->addError($e->getMessage()); 70 } 71 } 72 73 # Authentication process 74 public static function process($form,$user_id,$user_pwd,$user_key=null) 75 { 76 global $core, $_ctx; 77 78 # We check the user 79 $check_user = $core->auth->checkUser($user_id,$user_pwd,$user_key) === true; 80 81 $cookie_admin = http::browserUID(DC_MASTER_KEY.$user_id. 82 crypt::hmac(DC_MASTER_KEY,$user_pwd)).bin2hex(pack('a32',$user_id)); 83 84 if ($check_user && $core->auth->mustChangePassword()) 85 { 86 $form->login_data = join('/',array( 87 base64_encode($user_id), 88 $cookie_admin, 89 $form->user_remember == '' ? '0' : '1' 90 )); 91 92 if (!$core->auth->allowPassChange()) { 93 $_ctx->addError(__('You have to change your password before you can login.')); 94 } else { 95 $_ctx->addError(__('In order to login, you have to change your password now.')); 96 $_ctx->change_pwd = true; 97 } 98 } 99 elseif ($check_user && $form->safe_mode != '' && !$core->auth->isSuperAdmin()) 100 { 101 $_ctx->addError(__('Safe Mode can only be used for super administrators.')); 102 } 103 elseif ($check_user) 104 { 105 $core->session->start(); 106 $_SESSION['sess_user_id'] = $user_id; 107 $_SESSION['sess_browser_uid'] = http::browserUID(DC_MASTER_KEY); 108 109 if ($form->blog != '') { 110 $_SESSION['sess_blog_id'] = $form->blog; 111 } 112 113 if ($form->safe_mode != '' && $core->auth->isSuperAdmin()) { 114 $_SESSION['sess_safe_mode'] = true; 115 } 116 117 if ($form->user_remember != '') { 118 setcookie('dc_admin',$cookie_admin,strtotime('+15 days'),'','',DC_ADMIN_SSL); 119 } 120 121 http::redirect('index.php'); 122 } 123 else 124 { 125 if (isset($_COOKIE['dc_admin'])) { 126 unset($_COOKIE['dc_admin']); 127 setcookie('dc_admin',false,-600,'','',DC_ADMIN_SSL); 128 } 129 $_ctx->addError(__('Wrong username or password')); 130 } 131 } 132 133 # Login form action 134 public static function login($form) 135 { 136 global $_ctx; 137 138 if ($form->user_id != '' && $form->user_pwd != '') { 139 self::process($form,$form->user_id,$form->user_pwd); 140 } 141 142 # Send post values to form 143 $form->user_id = $form->user_id; 144 } 145 146 # Recover password form action 147 public static function recover($form) 148 { 149 global $core, $_ctx; 150 151 if ($form->user_id == '' || $form->user_email == '') { 152 return; 153 } 154 155 $user_id = $form->user_id; 156 $user_email = $form->user_email; 157 $page_url = http::getHost().$_SERVER['REQUEST_URI']; 158 159 try { 160 $recover_key = $core->auth->setRecoverKey($user_id,$user_email); 161 162 $subject = mail::B64Header('DotClear '.__('Password reset')); 163 $message = 164 __('Someone has requested to reset the password for the following site and username.')."\n\n". 165 $page_url."\n".__('Username:').' '.$user_id."\n\n". 166 __('To reset your password visit the following address, otherwise just ignore this email and nothing will happen.')."\n". 167 $page_url.'?akey='.$recover_key; 168 169 $headers[] = 'From: '.(defined('DC_ADMIN_MAILFROM') && DC_ADMIN_MAILFROM ? DC_ADMIN_MAILFROM : 'dotclear@local'); 170 $headers[] = 'Content-Type: text/plain; charset=UTF-8;'; 171 172 mail::sendMail($user_email,$subject,$message,$headers); 173 $_ctx->setAlert(sprintf(__('The e-mail was sent successfully to %s.'),$user_email)); 174 } 175 catch (Exception $e) { 176 $_ctx->addError($e->getMessage()); 177 } 178 179 # Send post values to form 180 $form->user_id = $form->user_id; 181 $form->user_email = $form->user_email; 182 } 183 184 # Change password form action 185 public static function change($form) 186 { 187 global $core, $_ctx; 188 189 if ($form->login_data) { 190 return; 191 } 192 $_ctx->change_pwd = true; 193 194 $new_pwd = (string) $form->new_pwd; 195 $new_pwd_c = (string) $form->new_pwd_c; 196 197 try { 198 $tmp_data = explode('/',$form->login_data); 199 if (count($tmp_data) != 3) { 200 throw new Exception(); 201 } 202 $data = array( 203 'user_id'=>base64_decode($tmp_data[0]), 204 'cookie_admin'=>$tmp_data[1], 205 'user_remember'=>$tmp_data[2]=='1' 206 ); 207 if ($data['user_id'] === false) { 208 throw new Exception(); 209 } 210 211 # Check login informations 212 $check_user = false; 213 if (isset($data['cookie_admin']) && strlen($data['cookie_admin']) == 104) 214 { 215 $user_id = substr($data['cookie_admin'],40); 216 $user_id = @unpack('a32',@pack('H*',$user_id)); 217 if (is_array($user_id)) 218 { 219 $user_id = $user_id[1]; 220 $user_key = substr($data['cookie_admin'],0,40); 221 $check_user = $core->auth->checkUser($user_id,null,$user_key) === true; 222 } 223 } 224 225 if (!$core->auth->allowPassChange() || !$check_user) { 226 $_ctx->change_pwd = false; 227 throw new Exception(); 228 } 229 230 if ($new_pwd != $new_pwd_c) { 231 throw new Exception(__("Passwords don't match")); 232 } 233 234 if ($core->auth->checkUser($user_id,$new_pwd) === true) { 235 throw new Exception(__("You didn't change your password.")); 236 } 237 238 $cur = $core->con->openCursor($core->prefix.'user'); 239 $cur->user_change_pwd = 0; 240 $cur->user_pwd = $new_pwd; 241 $core->updUser($core->auth->userID(),$cur); 242 243 $core->session->start(); 244 $_SESSION['sess_user_id'] = $user_id; 245 $_SESSION['sess_browser_uid'] = http::browserUID(DC_MASTER_KEY); 246 247 if ($data['user_remember']) { 248 setcookie('dc_admin',$data['cookie_admin'],strtotime('+15 days'),'','',DC_ADMIN_SSL); 249 } 250 251 http::redirect('index.php'); 252 } 253 catch (Exception $e) { 254 $_ctx->addError($e->getMessage()); 255 } 256 257 # Send post values to form 258 $form->login_data = $form->login_data; 259 } 260 } 261 262 # Form fields 263 $form = new dcForm($core,'auth','auth.php'); 264 $form 265 ->addField( 266 new dcFieldText('user_id','',array( 267 "label" => __('Username:')))) 268 ->addField( 269 new dcFieldPassword('user_pwd','',array( 270 "label" => __('Password:')))) 271 ->addField( 272 new dcFieldText('user_email','',array( 273 "label" => __('Email:')))) 274 ->addField( 275 new dcFieldPassword('new_pwd','',array( 276 "label" => __('New password:')))) 277 ->addField( 278 new dcFieldPassword('new_pwd_c','',array( 279 "label" => __('Confirm password:')))) 280 ->addField( 281 new dcFieldCheckbox ('user_remenber',1,array( 282 "label" => __('Remember my ID on this computer')))) 283 ->addField( 284 new dcFieldSubmit('auth_login',__('log in'),array( 285 'action' => array('adminPageAuth','login')))) 286 ->addField( 287 new dcFieldSubmit('auth_recover',__('recover'),array( 288 'action' => array('adminPageAuth','recover')))) 289 ->addField( 290 new dcFieldSubmit('auth_change',__('change'),array( 291 'action' => array('adminPageAuth','change')))) 292 ->addField( 293 new dcFieldHidden ('safe_mode','0')) 294 ->addField( 295 new dcFieldHidden ('recover','0')) 296 ->addField( 297 new dcFieldHidden ('login_data','')) 298 ->addField( 299 new dcFieldHidden ('blog','')); 300 301 # Context variables 302 $_ctx->allow_pass_change = $core->auth->allowPassChange(); 303 $_ctx->change_pwd = $core->auth->allowPassChange() && $form->new_pwd != '' && $form->new_pwd_c != '' && $form->login_data != ''; 304 $_ctx->recover = $form->recover = $core->auth->allowPassChange() && !empty($_REQUEST['recover']); 305 $_ctx->setSafeMode(!empty($_REQUEST['safe_mode'])); 306 $form->safe_mode = !empty($_REQUEST['safe_mode']); 307 $_ctx->akey = false; 308 309 # If we have no POST login informations and have COOKIE login informations, go throug auth process 310 if ($form->user_id == '' && $form->user_pwd == '' 311 && isset($_COOKIE['dc_admin']) && strlen($_COOKIE['dc_admin']) == 104) { 312 61 313 # If we have a remember cookie, go through auth process with user_key 62 314 $user_id = substr($_COOKIE['dc_admin'],40); 63 315 $user_id = @unpack('a32',@pack('H*',$user_id)); 64 if (is_array($user_id))65 {316 317 if (is_array($user_id)) { 66 318 $user_id = $user_id[1]; 67 319 $user_key = substr($_COOKIE['dc_admin'],0,40); 68 $user_pwd = null; 69 } 70 else 71 { 72 $user_id = null; 73 } 74 } 75 76 # Recover password 77 if ($recover && !empty($_POST['user_id']) && !empty($_POST['user_email'])) 78 { 79 $user_id = !empty($_POST['user_id']) ? $_POST['user_id'] : null; 80 $user_email = !empty($_POST['user_email']) ? $_POST['user_email'] : ''; 81 try 82 { 83 $recover_key = $core->auth->setRecoverKey($user_id,$user_email); 84 85 $subject = mail::B64Header('DotClear '.__('Password reset')); 86 $message = 87 __('Someone has requested to reset the password for the following site and username.')."\n\n". 88 $page_url."\n".__('Username:').' '.$user_id."\n\n". 89 __('To reset your password visit the following address, otherwise just ignore this email and nothing will happen.')."\n". 90 $page_url.'?akey='.$recover_key; 91 92 $headers[] = 'From: '.(defined('DC_ADMIN_MAILFROM') && DC_ADMIN_MAILFROM ? DC_ADMIN_MAILFROM : 'dotclear@local'); 93 $headers[] = 'Content-Type: text/plain; charset=UTF-8;'; 94 95 mail::sendMail($user_email,$subject,$message,$headers); 96 $msg = sprintf(__('The e-mail was sent successfully to %s.'),$user_email); 97 } 98 catch (Exception $e) 99 { 100 $err = $e->getMessage(); 101 } 102 } 103 # Send new password 104 elseif ($akey) 105 { 106 try 107 { 108 $recover_res = $core->auth->recoverUserPassword($akey); 109 110 $subject = mb_encode_mimeheader('DotClear '.__('Your new password'),'UTF-8','B'); 111 $message = 112 __('Username:').' '.$recover_res['user_id']."\n". 113 __('Password:').' '.$recover_res['new_pass']."\n\n". 114 preg_replace('/\?(.*)$/','',$page_url); 115 116 $headers[] = 'From: dotclear@'.$_SERVER['HTTP_HOST']; 117 $headers[] = 'Content-Type: text/plain; charset=UTF-8;'; 118 119 mail::sendMail($recover_res['user_email'],$subject,$message,$headers); 120 $msg = __('Your new password is in your mailbox.'); 121 } 122 catch (Exception $e) 123 { 124 $err = $e->getMessage(); 125 } 126 } 127 # Change password and retry to log 128 elseif ($change_pwd) 129 { 130 try 131 { 132 $tmp_data = explode('/',$_POST['login_data']); 133 if (count($tmp_data) != 3) { 134 throw new Exception(); 135 } 136 $data = array( 137 'user_id'=>base64_decode($tmp_data[0]), 138 'cookie_admin'=>$tmp_data[1], 139 'user_remember'=>$tmp_data[2]=='1' 140 ); 141 if ($data['user_id'] === false) { 142 throw new Exception(); 143 } 144 145 # Check login informations 146 $check_user = false; 147 if (isset($data['cookie_admin']) && strlen($data['cookie_admin']) == 104) 148 { 149 $user_id = substr($data['cookie_admin'],40); 150 $user_id = @unpack('a32',@pack('H*',$user_id)); 151 if (is_array($user_id)) 152 { 153 $user_id = $user_id[1]; 154 $user_key = substr($data['cookie_admin'],0,40); 155 $check_user = $core->auth->checkUser($user_id,null,$user_key) === true; 156 } 157 } 158 159 if (!$core->auth->allowPassChange() || !$check_user) { 160 $change_pwd = false; 161 throw new Exception(); 162 } 163 164 if ($_POST['new_pwd'] != $_POST['new_pwd_c']) { 165 throw new Exception(__("Passwords don't match")); 166 } 167 168 if ($core->auth->checkUser($user_id,$_POST['new_pwd']) === true) { 169 throw new Exception(__("You didn't change your password.")); 170 } 171 172 $cur = $core->con->openCursor($core->prefix.'user'); 173 $cur->user_change_pwd = 0; 174 $cur->user_pwd = $_POST['new_pwd']; 175 $core->updUser($core->auth->userID(),$cur); 176 177 $core->session->start(); 178 $_SESSION['sess_user_id'] = $user_id; 179 $_SESSION['sess_browser_uid'] = http::browserUID(DC_MASTER_KEY); 180 181 if ($data['user_remember']) 182 { 183 setcookie('dc_admin',$data['cookie_admin'],strtotime('+15 days'),'','',DC_ADMIN_SSL); 184 } 185 186 http::redirect('index.php'); 187 } 188 catch (Exception $e) 189 { 190 $err = $e->getMessage(); 191 } 192 } 193 # Try to log 194 elseif ($user_id !== null && ($user_pwd !== null || $user_key !== null)) 195 { 196 # We check the user 197 $check_user = $core->auth->checkUser($user_id,$user_pwd,$user_key) === true; 198 199 $cookie_admin = http::browserUID(DC_MASTER_KEY.$user_id. 200 crypt::hmac(DC_MASTER_KEY,$user_pwd)).bin2hex(pack('a32',$user_id)); 201 202 if ($check_user && $core->auth->mustChangePassword()) 203 { 204 $login_data = join('/',array( 205 base64_encode($user_id), 206 $cookie_admin, 207 empty($_POST['user_remember'])?'0':'1' 208 )); 209 210 if (!$core->auth->allowPassChange()) { 211 $err = __('You have to change your password before you can login.'); 212 } else { 213 $err = __('In order to login, you have to change your password now.'); 214 $change_pwd = true; 215 } 216 } 217 elseif ($check_user && !empty($_POST['safe_mode']) && !$core->auth->isSuperAdmin()) 218 { 219 $err = __('Safe Mode can only be used for super administrators.'); 220 } 221 elseif ($check_user) 222 { 223 $core->session->start(); 224 $_SESSION['sess_user_id'] = $user_id; 225 $_SESSION['sess_browser_uid'] = http::browserUID(DC_MASTER_KEY); 226 227 if (!empty($_POST['blog'])) { 228 $_SESSION['sess_blog_id'] = $_POST['blog']; 229 } 230 231 if (!empty($_POST['safe_mode']) && $core->auth->isSuperAdmin()) { 232 $_SESSION['sess_safe_mode'] = true; 233 } 234 235 if (!empty($_POST['user_remember'])) { 236 setcookie('dc_admin',$cookie_admin,strtotime('+15 days'),'','',DC_ADMIN_SSL); 237 } 238 239 http::redirect('index.php'); 240 } 241 else 242 { 243 if (isset($_COOKIE['dc_admin'])) { 244 unset($_COOKIE['dc_admin']); 245 setcookie('dc_admin',false,-600,'','',DC_ADMIN_SSL); 246 } 247 $err = __('Wrong username or password'); 248 } 320 $user_pwd = ''; 321 322 adminPageAuth::process($form,$user_id,$user_pwd,$user_key); 323 } 324 } 325 # If we have an akey, go throug send password process 326 elseif ($core->auth->allowPassChange() && !empty($_GET['akey'])) { 327 adminPageAuth::send($_GET['akey']); 249 328 } 250 329 251 330 if (isset($_GET['user'])) { 252 $user_id = $_GET['user']; 253 } 254 255 header('Content-Type: text/html; charset=UTF-8'); 331 $form->user_id = $_GET['user']; 332 } 333 334 $form->setup(); 335 336 $core->tpl->display('auth.html.twig'); 256 337 ?> 257 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">258 <html xmlns="http://www.w3.org/1999/xhtml"259 xml:lang="<?php echo $dlang; ?>" lang="<?php echo $dlang; ?>">260 <head>261 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />262 <meta http-equiv="Content-Script-Type" content="text/javascript" />263 <meta http-equiv="Content-Style-Type" content="text/css" />264 <meta http-equiv="Content-Language" content="<?php echo $dlang; ?>" />265 <meta name="ROBOTS" content="NOARCHIVE,NOINDEX,NOFOLLOW" />266 <meta name="GOOGLEBOT" content="NOSNIPPET" />267 <meta name="viewport" content="width=device-width, initial-scale=1.0" />268 <title><?php echo html::escapeHTML(DC_VENDOR_NAME); ?></title>269 270 <?php271 echo dcPage::jsLoadIE7();272 echo dcPage::jsCommon();273 ?>274 275 <link rel="stylesheet" href="style/default.css" type="text/css" media="screen" />276 277 <?php278 # --BEHAVIOR-- loginPageHTMLHead279 $core->callBehavior('loginPageHTMLHead');280 ?>281 282 <script type="text/javascript">283 //<![CDATA[284 $(window).load(function() {285 var uid = $('input[name=user_id]');286 var upw = $('input[name=user_pwd]');287 uid.focus();288 289 if (upw.length == 0) { return; }290 291 if ($.browser.mozilla) {292 uid.keypress(processKey);293 } else {294 uid.keydown(processKey);295 }296 function processKey(evt) {297 if (evt.keyCode == 13 && upw.val() == '') {298 upw.focus();299 return false;300 }301 return true;302 };303 $.cookie('dc_admin_test_cookie',true);304 if ($.cookie('dc_admin_test_cookie')) {305 $('#cookie_help').hide();306 $.cookie('dc_admin_test_cookie', '', {'expires': -1});307 } else {308 $('#cookie_help').show();309 }310 $('#issue #more').toggleWithLegend($('#issue').children().not('#more'));311 });312 //]]>313 </script>314 </head>315 316 <body id="dotclear-admin" class="auth">317 318 <form action="auth.php" method="post" id="login-screen">319 <h1><?php echo html::escapeHTML(DC_VENDOR_NAME); ?></h1>320 321 <?php322 if ($err) {323 echo '<div class="error">'.$err.'</div>';324 }325 if ($msg) {326 echo '<p class="message">'.$msg.'</p>';327 }328 329 if ($akey)330 {331 echo '<p><a href="auth.php">'.__('Back to login screen').'</a></p>';332 }333 elseif ($recover)334 {335 echo336 '<fieldset><legend>'.__('Request a new password').'</legend>'.337 '<p><label for="user_id">'.__('Username:').'</label> '.338 form::field(array('user_id','user_id'),20,32,html::escapeHTML($user_id)).'</p>'.339 340 '<p><label for="user_email">'.__('Email:').'</label> '.341 form::field(array('user_email','user_email'),20,255,html::escapeHTML($user_email)).'</p>'.342 343 '<p><input type="submit" value="'.__('recover').'" />'.344 form::hidden(array('recover'),1).'</p>'.345 '</fieldset>'.346 347 '<div id="issue">'.348 '<p><a href="auth.php">'.__('Back to login screen').'</a></p></div>';349 }350 elseif ($change_pwd)351 {352 echo353 '<fieldset><legend>'.__('Change your password').'</legend>'.354 '<p><label for="new_pwd">'.__('New password:').'</label> '.355 form::password(array('new_pwd','new_pwd'),20,255).'</p>'.356 357 '<p><label for="new_pwd_c">'.__('Confirm password:').'</label> '.358 form::password(array('new_pwd_c','new_pwd_c'),20,255).'</p>'.359 '</fielset>'.360 361 '<p><input type="submit" value="'.__('change').'" />'.362 form::hidden('login_data',$login_data).'</p>';363 }364 else365 {366 if (is_callable(array($core->auth,'authForm')))367 {368 echo $core->auth->authForm($user_id);369 }370 else371 {372 if ($safe_mode) {373 echo '<fieldset>';374 echo '<legend>'.__('Safe mode login').'</legend>';375 echo376 '<p class="form-note info">'.377 __('This mode allows you to login without activating any of your plugins. This may be useful to solve compatibility problems').' <br />'.378 __('Disable or delete any plugin suspected to cause trouble, then log out and log back in normally.').379 '</p>';380 }381 else {382 echo '<div class="fieldset">';383 }384 385 echo386 '<p><label for="user_id">'.__('Username:').'</label> '.387 form::field(array('user_id','user_id'),20,32,html::escapeHTML($user_id)).'</p>'.388 389 '<p><label for="user_pwd">'.__('Password:').'</label> '.390 form::password(array('user_pwd','user_pwd'),20,255).'</p>'.391 392 '<p>'.393 form::checkbox(array('user_remember','user_remember'),1).394 '<label for="user_remember" class="classic">'.395 __('Remember my ID on this computer').'</label></p>'.396 397 '<p><input class="add button" type="submit" value="'.__('log in').'" /></p>';398 399 if (!empty($_REQUEST['blog'])) {400 echo form::hidden('blog',html::escapeHTML($_REQUEST['blog']));401 }402 if($safe_mode) {403 echo404 form::hidden('safe_mode',1).405 '</fieldset>';406 }407 else {408 echo '</div>';409 }410 echo411 '<p id="cookie_help" class="error">'.__('You must accept cookies in order to use the private area.').'</p>';412 413 echo '<div id="issue">';414 415 if ($safe_mode) {416 echo417 '<p><a href="auth.php" id="normal_mode_link">'.__('Get back to normal authentication').'</a></p>';418 } else {419 echo '<p id="more"><strong>'.__('Connection issue?').'</strong></p>';420 if ($core->auth->allowPassChange()) {421 echo '<p><a href="auth.php?recover=1">'.__('I forgot my password').'</a></p>';422 }423 echo '<p><a href="auth.php?safe_mode=1" id="safe_mode_link">'.__('I want to log in in safe mode').'</a></p>';424 }425 426 echo '</div>';427 }428 }429 ?>430 </form>431 </body>432 </html> -
admin/index.php
r1280 r1315 4 4 # This file is part of Dotclear 2. 5 5 # 6 # Copyright (c) 2003-201 3Olivier Meunier & Association Dotclear6 # Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 13 13 if (!empty($_GET['pf'])) { 14 14 require dirname(__FILE__).'/../inc/load_plugin_file.php'; 15 exit; 16 } 17 if (!empty($_GET['tf'])) { 18 define('DC_CONTEXT_ADMIN',true); 19 require dirname(__FILE__).'/../inc/load_theme_file.php'; 15 20 exit; 16 21 } … … 43 48 $plugins_install = $core->plugins->installModules(); 44 49 50 # Send plugins install messages to templates 51 if (!empty($plugins_install['success'])) { 52 $_ctx->addMessagesList(__('Following plugins have been installed:'),$plugins_install['success']); 53 } 54 if (!empty($plugins_install['failure'])) { 55 $_ctx->addMessagesList(__('Following plugins have not been installed:'),$plugins_install['failure']); 56 } 57 58 # Send plugins errors messages to templates 59 $_ctx->modules_errors = $core->auth->isSuperAdmin() ? $core->plugins->getErrors() : array(); 60 61 # Send Dotclear updates notifications to tempaltes 62 $_ctx->updater = array(); 63 if ($core->auth->isSuperAdmin() && is_readable(DC_DIGESTS)) { 64 65 $updater = new dcUpdate(DC_UPDATE_URL,'dotclear',DC_UPDATE_VERSION,DC_TPL_CACHE.'/versions'); 66 $new_v = $updater->check(DC_VERSION); 67 $version_info = $new_v ? $updater->getInfoURL() : ''; 68 69 if ($updater->getNotify() && $new_v) { 70 $_ctx->updater = array( 71 'new_version' => $new_v, 72 'version_info' => $version_info 73 ); 74 } 75 } 76 45 77 # Check dashboard module prefs 46 78 $ws = $core->auth->user_prefs->addWorkspace('dashboard'); 79 80 # Doclinks prefs 47 81 if (!$core->auth->user_prefs->dashboard->prefExists('doclinks')) { 48 82 if (!$core->auth->user_prefs->dashboard->prefExists('doclinks',true)) { … … 51 85 $core->auth->user_prefs->dashboard->put('doclinks',true,'boolean'); 52 86 } 87 88 # Send doclinks to templates 89 $_ctx->dashboard_doclinks = array(); 90 if ($core->auth->user_prefs->dashboard->doclinks && !empty($__resources['doc'])) { 91 $_ctx->dashboard_doclinks = $__resources['doc']; 92 } 93 94 # Dcnews prefs 53 95 if (!$core->auth->user_prefs->dashboard->prefExists('dcnews')) { 54 96 if (!$core->auth->user_prefs->dashboard->prefExists('dcnews',true)) { … … 57 99 $core->auth->user_prefs->dashboard->put('dcnews',true,'boolean'); 58 100 } 101 102 # Send dcnews to templates 103 $_ctx->dashboard_dcnews = array(); 104 if ($core->auth->user_prefs->dashboard->dcnews && !empty($__resources['rss_news'])) { 105 try 106 { 107 $feed_reader = new feedReader; 108 $feed_reader->setCacheDir(DC_TPL_CACHE); 109 $feed_reader->setTimeout(2); 110 $feed_reader->setUserAgent('Dotclear - http://www.dotclear.org/'); 111 $feed = $feed_reader->parse($__resources['rss_news']); 112 if ($feed) { 113 $items = array(); 114 $i = 1; 115 foreach ($feed->items as $item) { 116 $items[] = array( 117 'title' => $item->title, 118 'link' => isset($item->link) ? $item->link : '', 119 'date' => dt::dt2str(__('%d %B %Y'),$item->pubdate,'Europe/Paris'), 120 'content' => html::clean($item->content) 121 ); 122 $i++; 123 if ($i > 3) { break; } 124 } 125 $_ctx->dashboard_dcnews = $items; 126 } 127 } 128 catch (Exception $e) {} 129 } 130 131 # Quick entry prefs 59 132 if (!$core->auth->user_prefs->dashboard->prefExists('quickentry')) { 60 133 if (!$core->auth->user_prefs->dashboard->prefExists('quickentry',true)) { … … 62 135 } 63 136 $core->auth->user_prefs->dashboard->put('quickentry',true,'boolean'); 137 } 138 139 # Send quick entry to templates 140 $_ctx->dashboard_quickentry = false; 141 if ($core->auth->user_prefs->dashboard->quickentry &&$core->auth->check('usage,contentadmin',$core->blog->id)) 142 { 143 $categories_combo = array(' ' => ''); 144 try { 145 $categories = $core->blog->getCategories(array('post_type'=>'post')); 146 while ($categories->fetch()) { 147 $categories_combo[$categories->cat_id] = 148 str_repeat(' ',$categories->level-1). 149 ($categories->level-1 == 0 ? '' : '• '). 150 html::escapeHTML($categories->cat_title); 151 } 152 } catch (Exception $e) { } 153 154 $form = new dcForm($core,array('quickentry','quick-entry'),'post.php'); 155 $form 156 ->addField( 157 new dcFieldText('post_title','', array( 158 'size' => 20, 159 'required' => true, 160 'label' => __('Title')))) 161 ->addField( 162 new dcFieldTextArea('post_content','', array( 163 'required' => true, 164 'label' => __("Content:")))) 165 ->addField( 166 new dcFieldCombo('cat_id','',$categories_combo,array( 167 "label" => __('Category:')))) 168 ->addField( 169 new dcFieldSubmit('save',__('Save'),array( 170 'action' => 'savePost'))) 171 ->addField( 172 new dcFieldHidden ('post_status',-2)) 173 ->addField( 174 new dcFieldHidden ('post_format',$core->auth->getOption('post_format'))) 175 ->addField( 176 new dcFieldHidden ('post_excerpt','')) 177 ->addField( 178 new dcFieldHidden ('post_lang',$core->auth->getInfo('user_lang'))) 179 ->addField( 180 new dcFieldHidden ('post_notes','')) 181 ; 182 if ($core->auth->check('publish',$core->blog->id)) { 183 $form->addField( 184 new dcFieldHidden ('save-publish',__('Save and publish'))); 185 } 186 187 $_ctx->dashboard_quickentry = true; 64 188 } 65 189 … … 118 242 } 119 243 120 # Latest news for dashboard 244 # Send dashboard icons to templates 245 $icons = array(); 246 foreach ($__dashboard_icons as $i) { 247 $icons[] = array( 248 'title' => $i[0], 249 'url' => $i[1], 250 'img' => dc_admin_icon_url($i[2]) 251 ); 252 } 253 $_ctx->dashboard_icons = $icons; 254 255 # Dashboard items 121 256 $__dashboard_items = new ArrayObject(array(new ArrayObject,new ArrayObject)); 122 123 # Documentation links124 $dashboardItem = 0;125 if ($core->auth->user_prefs->dashboard->doclinks) {126 if (!empty($__resources['doc']))127 {128 $doc_links = '<h3>'.__('Documentation and support').'</h3><ul>';129 130 foreach ($__resources['doc'] as $k => $v) {131 $doc_links .= '<li><a href="'.$v.'" title="'.$k.' '.__('(external link)').'">'.$k.'</a></li>';132 }133 134 $doc_links .= '</ul>';135 $__dashboard_items[$dashboardItem][] = $doc_links;136 $dashboardItem++;137 }138 }139 140 if ($core->auth->user_prefs->dashboard->dcnews) {141 try142 {143 if (empty($__resources['rss_news'])) {144 throw new Exception();145 }146 147 $feed_reader = new feedReader;148 $feed_reader->setCacheDir(DC_TPL_CACHE);149 $feed_reader->setTimeout(2);150 $feed_reader->setUserAgent('Dotclear - http://www.dotclear.org/');151 $feed = $feed_reader->parse($__resources['rss_news']);152 if ($feed)153 {154 $latest_news = '<h3>'.__('Latest news').'</h3><dl id="news">';155 $i = 1;156 foreach ($feed->items as $item)157 {158 $dt = isset($item->link) ? '<a href="'.$item->link.'" title="'.$item->title.' '.__('(external link)').'">'.159 $item->title.'</a>' : $item->title;160 161 if ($i < 3) {162 $latest_news .=163 '<dt>'.$dt.'</dt>'.164 '<dd><p><strong>'.dt::dt2str(__('%d %B %Y:'),$item->pubdate,'Europe/Paris').'</strong> '.165 '<em>'.text::cutString(html::clean($item->content),120).'...</em></p></dd>';166 } else {167 $latest_news .=168 '<dt>'.$dt.'</dt>'.169 '<dd>'.dt::dt2str(__('%d %B %Y:'),$item->pubdate,'Europe/Paris').'</dd>';170 }171 $i++;172 if ($i > 3) { break; }173 }174 $latest_news .= '</dl>';175 $__dashboard_items[$dashboardItem][] = $latest_news;176 $dashboardItem++;177 }178 }179 catch (Exception $e) {}180 }181 182 257 $core->callBehavior('adminDashboardItems', $core, $__dashboard_items); 183 258 259 # Send dashboard items to templates 260 $items = array(); 261 foreach ($__dashboard_items as $i) { 262 if ($i->count() > 0) { 263 foreach ($i as $v) { 264 $items[] = $v; 265 } 266 } 267 } 268 $_ctx->dashboard_items = $items; 269 184 270 # Dashboard content 185 $dashboardContents = '';186 271 $__dashboard_contents = new ArrayObject(array(new ArrayObject,new ArrayObject)); 187 272 $core->callBehavior('adminDashboardContents', $core, $__dashboard_contents); 188 273 189 /* DISPLAY 190 -------------------------------------------------------- */ 191 dcPage::open(__('Dashboard'), 192 dcPage::jsToolBar(). 193 dcPage::jsLoad('js/_index.js'). 194 # --BEHAVIOR-- adminDashboardHeaders 195 $core->callBehavior('adminDashboardHeaders') 196 ); 197 198 echo '<h2>'.html::escapeHTML($core->blog->name).' › <span class="page-title">'.__('Dashboard').'</span></h2>'; 199 200 if ($core->auth->getInfo('user_default_blog') != $core->blog->id && $core->auth->blog_count > 1) { 201 echo 202 '<p><a href="index.php?default_blog=1" class="button">'.__('Make this blog my default blog').'</a></p>'; 203 } 204 274 # Send dashboard contents to templates 275 $contents = array(); 276 foreach ($__dashboard_contents as $i) { 277 if ($i->count() > 0) { 278 foreach ($i as $v) { 279 $contents[] = $v; 280 } 281 } 282 } 283 $_ctx->dashboard_contents = $contents; 284 285 # Blog status message 205 286 if ($core->blog->status == 0) { 206 echo '<p class="static-msg">'.__('This blog is offline').'</p>';287 $_ctx->addMessageStatic(__('This blog is offline')); 207 288 } elseif ($core->blog->status == -1) { 208 echo '<p class="static-msg">'.__('This blog is removed').'</p>'; 209 } 210 289 $_ctx->addMessageStatic(__('This blog is removed')); 290 } 291 292 # Config errors messages 211 293 if (!defined('DC_ADMIN_URL') || !DC_ADMIN_URL) { 212 echo 213 '<p class="static-msg">'. 214 sprintf(__('%s is not defined, you should edit your configuration file.'),'DC_ADMIN_URL'). 215 ' '.__('See <a href="http://dotclear.org/documentation/2.0/admin/config">documentation</a> for more information.'). 216 '</p>'; 217 } 218 294 $_ctx->addMessageStatic( 295 sprintf(__('%s is not defined, you should edit your configuration file.'),'DC_ADMIN_URL').' '. 296 __('See <a href="http://dotclear.org/documentation/2.0/admin/config">documentation</a> for more information.') 297 ); 298 } 219 299 if (!defined('DC_ADMIN_MAILFROM') || !DC_ADMIN_MAILFROM) { 220 echo 221 '<p class="static-msg">'. 222 sprintf(__('%s is not defined, you should edit your configuration file.'),'DC_ADMIN_MAILFROM'). 223 ' '.__('See <a href="http://dotclear.org/documentation/2.0/admin/config">documentation</a> for more information.'). 224 '</p>'; 225 } 226 227 # Plugins install messages 228 if (!empty($plugins_install['success'])) 229 { 230 echo '<div class="static-msg">'.__('Following plugins have been installed:').'<ul>'; 231 foreach ($plugins_install['success'] as $k => $v) { 232 echo '<li>'.$k.'</li>'; 233 } 234 echo '</ul></div>'; 235 } 236 if (!empty($plugins_install['failure'])) 237 { 238 echo '<div class="error">'.__('Following plugins have not been installed:').'<ul>'; 239 foreach ($plugins_install['failure'] as $k => $v) { 240 echo '<li>'.$k.' ('.$v.')</li>'; 241 } 242 echo '</ul></div>'; 243 } 244 245 # Dashboard columns (processed first, as we need to know the result before displaying the icons.) 246 $dashboardItems = ''; 247 248 # Dotclear updates notifications 249 if ($core->auth->isSuperAdmin() && is_readable(DC_DIGESTS)) 250 { 251 $updater = new dcUpdate(DC_UPDATE_URL,'dotclear',DC_UPDATE_VERSION,DC_TPL_CACHE.'/versions'); 252 $new_v = $updater->check(DC_VERSION); 253 $version_info = $new_v ? $updater->getInfoURL() : ''; 254 255 if ($updater->getNotify() && $new_v) { 256 $dashboardItems .= 257 '<div id="upg-notify" class="static-msg"><p>'.sprintf(__('Dotclear %s is available!'),$new_v).'</p> '. 258 '<ul><li><strong><a href="update.php">'.sprintf(__('Upgrade now'),$new_v).'</a></strong>'. 259 '</li><li><a href="update.php?hide_msg=1">'.__('Remind me later').'</a>'. 260 ($version_info ? ' </li><li><a href="'.$version_info.'">'.__('information about this version').'</a>' : ''). 261 '</li></ul></div>'; 262 } 263 } 264 265 # Errors modules notifications 266 if ($core->auth->isSuperAdmin()) 267 { 268 $list = array(); 269 foreach ($core->plugins->getErrors() as $k => $error) { 270 $list[] = '<li>'.$error.'</li>'; 271 } 272 273 if (count($list) > 0) { 274 $dashboardItems .= 275 '<div id="module-errors" class="error"><p>'.__('Some plugins are installed twice:').'</p> '. 276 '<ul>'.implode("\n",$list).'</ul></div>'; 277 } 278 279 } 280 281 foreach ($__dashboard_items as $i) 282 { 283 if ($i->count() > 0) 284 { 285 $dashboardItems .= '<div>'; 286 foreach ($i as $v) { 287 $dashboardItems .= $v; 288 } 289 $dashboardItems .= '</div>'; 290 } 291 } 292 293 # Dashboard icons 294 echo '<div id="dashboard-main"'.($dashboardItems ? '' : ' class="fullwidth"').'><div id="icons">'; 295 foreach ($__dashboard_icons as $i) 296 { 297 echo 298 '<p><a href="'.$i[1].'"><img src="'.dc_admin_icon_url($i[2]).'" alt="" />'. 299 '<br /><span>'.$i[0].'</span></a></p>'; 300 } 301 echo '</div>'; 302 303 if ($core->auth->user_prefs->dashboard->quickentry) { 304 if ($core->auth->check('usage,contentadmin',$core->blog->id)) 305 { 306 $categories_combo = array(' ' => ''); 307 try { 308 $categories = $core->blog->getCategories(array('post_type'=>'post')); 309 while ($categories->fetch()) { 310 $categories_combo[] = new formSelectOption( 311 str_repeat(' ',$categories->level-1). 312 ($categories->level-1 == 0 ? '' : '• ').html::escapeHTML($categories->cat_title), 313 $categories->cat_id 314 ); 315 } 316 } catch (Exception $e) { } 317 318 echo 319 '<div id="quick">'. 320 '<h3>'.__('Quick entry').'</h3>'. 321 '<form id="quick-entry" action="post.php" method="post">'. 322 '<fieldset><legend>'.__('New entry').'</legend>'. 323 '<p class="col"><label for="post_title" class="required"><abbr title="'.__('Required field').'">*</abbr> '.__('Title:'). 324 form::field('post_title',20,255,'','maximal'). 325 '</label></p>'. 326 '<p class="area"><label class="required" '. 327 'for="post_content"><abbr title="'.__('Required field').'">*</abbr> '.__('Content:').'</label> '. 328 form::textarea('post_content',50,7). 329 '</p>'. 330 '<p><label for="cat_id" class="classic">'.__('Category:').' '. 331 form::combo('cat_id',$categories_combo).'</label></p>'. 332 '<p><input type="submit" value="'.__('Save').'" name="save" /> '. 333 ($core->auth->check('publish',$core->blog->id) 334 ? '<input type="hidden" value="'.__('Save and publish').'" name="save-publish" />' 335 : ''). 336 $core->formNonce(). 337 form::hidden('post_status',-2). 338 form::hidden('post_format',$core->auth->getOption('post_format')). 339 form::hidden('post_excerpt',''). 340 form::hidden('post_lang',$core->auth->getInfo('user_lang')). 341 form::hidden('post_notes',''). 342 '</p>'. 343 '</fieldset>'. 344 '</form>'. 345 '</div>'; 346 } 347 } 348 349 foreach ($__dashboard_contents as $i) 350 { 351 if ($i->count() > 0) 352 { 353 $dashboardContents .= '<div>'; 354 foreach ($i as $v) { 355 $dashboardContents .= $v; 356 } 357 $dashboardContents .= '</div>'; 358 } 359 } 360 echo ($dashboardContents ? '<div id="dashboard-contents">'.$dashboardContents.'</div>' : ''); 361 362 echo '</div>'; 363 364 echo ($dashboardItems ? '<div id="dashboard-items">'.$dashboardItems.'</div>' : ''); 365 366 dcPage::close(); 300 $_ctx->addMessageStatic( 301 sprintf(__('%s is not defined, you should edit your configuration file.'),'DC_ADMIN_MAILFROM').' '. 302 __('See <a href="http://dotclear.org/documentation/2.0/admin/config">documentation</a> for more information.') 303 ); 304 } 305 306 $_ctx->fillPageTitle(__('Dashboard')); 307 $core->tpl->display('index.html.twig'); 367 308 ?> -
admin/plugin.php
r1179 r1315 4 4 # This file is part of Dotclear 2. 5 5 # 6 # Copyright (c) 2003-201 3Olivier Meunier & Association Dotclear6 # Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 15 15 dcPage::check('usage,contentadmin'); 16 16 17 $has_content = false; 17 18 $p_file = ''; 18 19 $p = !empty($_REQUEST['p']) ? $_REQUEST['p'] : null; 19 $popup = (integer) !empty($_REQUEST['popup']); 20 21 if ($popup) { 22 $open_f = array('dcPage','openPopup'); 23 $close_f = array('dcPage','closePopup'); 24 } else { 25 $open_f = array('dcPage','open'); 26 $close_f = array('dcPage','close'); 27 } 20 $popup = $_ctx->popup = (integer) !empty($_REQUEST['popup']); 28 21 29 22 if ($core->plugins->moduleExists($p)) { 30 23 $p_file = $core->plugins->moduleRoot($p).'/index.php'; 31 24 } 25 if (file_exists($p_file)) { 32 26 33 if (file_exists($p_file)) 34 { 35 # Loading plugin 27 //* Keep this for old style plugins using dcPage 28 if ($popup) { 29 $open_f = array('dcPage','openPopup'); 30 $close_f = array('dcPage','closePopup'); 31 } else { 32 $open_f = array('dcPage','open'); 33 $close_f = array('dcPage','close'); 34 } 35 36 36 $p_info = $core->plugins->getModules($p); 37 38 37 $p_url = 'plugin.php?p='.$p; 39 40 $p_title = 'no content - plugin'; 41 $p_head = ''; 42 $p_content = '<p>'.__('No content found on this plugin.').'</p>'; 43 38 $p_title = $p_head = $p_content = ''; 39 //*/ 40 # Get page content 44 41 ob_start(); 45 42 include $p_file; 46 43 $res = ob_get_contents(); 47 44 ob_end_clean(); 48 49 if (preg_match('|<head>(.*?)</head|ms',$res,$m)) { 50 if (preg_match('|<title>(.*?)</title>|ms',$m[1],$mt)) { 51 $p_title = $mt[1]; 52 } 45 46 # Check context and display 47 if ($_ctx->hasPageTitle() && !empty($res)) { 48 $has_content = true; 49 echo $res; 50 } 51 //* Keep this for old style plugins using dcPage 52 elseif (!$_ctx->hasPageTitle()) { 53 53 54 if (preg_match_all('|(<script.*?>.*?</script>)|ms',$m[1],$ms)) { 55 foreach ($ms[1] as $v) { 56 $p_head .= $v."\n"; 54 if (preg_match('|<head>(.*?)</head|ms',$res,$m)) { 55 if (preg_match('|<title>(.*?)</title>|ms',$m[1],$mt)) { 56 $p_title = $mt[1]; 57 } 58 59 if (preg_match_all('|(<script.*?>.*?</script>)|ms',$m[1],$ms)) { 60 foreach ($ms[1] as $v) { 61 $p_head .= $v."\n"; 62 } 63 } 64 65 if (preg_match_all('|(<style.*?>.*?</style>)|ms',$m[1],$ms)) { 66 foreach ($ms[1] as $v) { 67 $p_head .= $v."\n"; 68 } 69 } 70 71 if (preg_match_all('|(<link.*?/>)|ms',$m[1],$ms)) { 72 foreach ($ms[1] as $v) { 73 $p_head .= $v."\n"; 74 } 57 75 } 58 76 } 59 77 60 if (preg_match_all('|(<style.*?>.*?</style>)|ms',$m[1],$ms)) { 61 foreach ($ms[1] as $v) { 62 $p_head .= $v."\n"; 63 } 64 } 65 66 if (preg_match_all('|(<link.*?/>)|ms',$m[1],$ms)) { 67 foreach ($ms[1] as $v) { 68 $p_head .= $v."\n"; 69 } 78 if (preg_match('|<body.*?>(.+)</body>|ms',$res,$m)) { 79 $p_content = $m[1]; 80 81 call_user_func($open_f,$p_title,$p_head); 82 echo $p_content; 83 call_user_func($close_f); 84 85 $has_content = true; 70 86 } 71 87 } 72 73 if (preg_match('|<body.*?>(.+)</body>|ms',$res,$m)) { 74 $p_content = $m[1]; 75 } 76 77 call_user_func($open_f,$p_title,$p_head); 78 echo $p_content; 79 call_user_func($close_f); 88 //*/ 80 89 } 81 else 82 { 83 call_user_func($open_f,__('Plugin not found')); 84 85 echo '<h2 class="page-title">'.__('Plugin not found').'</h2>'; 86 87 echo '<p>'.__('The plugin you reached does not exist or does not have an admin page.').'</p>'; 88 89 call_user_func($close_f); 90 # No plugin or content found 91 if (!$has_content) { 92 $_ctx->fillPageTitle(__('Plugin not found')); 93 $_ctx->addError(__('The plugin you reached does not exist or does not have an admin page.')); 94 $core->tpl->display('plugin.html.twig'); 90 95 } 91 96 ?> -
admin/post.php
r1312 r1315 4 4 # This file is part of Dotclear 2. 5 5 # 6 # Copyright (c) 2003-201 3Olivier Meunier & Association Dotclear6 # Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 15 15 dcPage::check('usage,contentadmin'); 16 16 17 $post_id = ''; 18 $cat_id = ''; 19 $post_dt = ''; 20 $post_format = $core->auth->getOption('post_format'); 21 $post_password = ''; 22 $post_url = ''; 23 $post_lang = $core->auth->getInfo('user_lang'); 24 $post_title = ''; 25 $post_excerpt = ''; 26 $post_excerpt_xhtml = ''; 27 $post_content = ''; 28 $post_content_xhtml = ''; 29 $post_notes = ''; 30 $post_status = $core->auth->getInfo('user_post_status'); 31 $post_selected = false; 32 $post_open_comment = $core->blog->settings->system->allow_comments; 33 $post_open_tb = $core->blog->settings->system->allow_trackbacks; 17 function savePost($form) { 18 global $_ctx; 19 $_ctx->setAlert('save'); 20 21 } 22 23 function deletePost($form) { 24 print_r($form); exit; 25 } 34 26 35 27 $page_title = __('New entry'); … … 47 39 # If user can't publish 48 40 if (!$can_publish) { 49 $ post_status = -2;41 $form->post_status = -2; 50 42 } 51 43 … … 55 47 $categories = $core->blog->getCategories(array('post_type'=>'post')); 56 48 while ($categories->fetch()) { 57 $categories_combo[ ] = new formSelectOption(58 str_repeat(' ',$categories->level-1). ($categories->level-1 == 0 ? '' : '• ').html::escapeHTML($categories->cat_title),59 $categories->cat_id60 );49 $categories_combo[$categories->cat_id] = 50 str_repeat(' ',$categories->level-1). 51 ($categories->level-1 == 0 ? '' : '• '). 52 html::escapeHTML($categories->cat_title); 61 53 } 62 54 } catch (Exception $e) { } … … 64 56 # Status combo 65 57 foreach ($core->blog->getAllPostStatus() as $k => $v) { 66 $status_combo[$ v] = (string) $k;58 $status_combo[$k] = $v; 67 59 } 68 $img_status_pattern = '<img class="img_select_option" alt="%1$s" title="%1$s" src="images/%2$s" />';69 60 70 61 # Formaters combo … … 88 79 unset($rs); 89 80 90 # Validation flag 91 $bad_dt = false; 92 81 $form = new dcForm($core,'post','post.php'); 82 $form 83 ->addField( 84 new dcFieldText('post_title','', array( 85 'size' => 20, 86 'required' => true, 87 'label' => __('Title')))) 88 ->addField( 89 new dcFieldTextArea('post_excerpt','', array( 90 'cols' => 50, 91 'rows' => 5, 92 'label' => __("Excerpt:")))) 93 ->addField( 94 new dcFieldTextArea('post_content','', array( 95 'required' => true, 96 'label' => __("Content:")))) 97 ->addField( 98 new dcFieldTextArea('post_notes','', array( 99 'label' => __("Notes")))) 100 ->addField( 101 new dcFieldSubmit('save',__('Save'),array( 102 'action' => 'savePost'))) 103 ->addField( 104 new dcFieldSubmit('delete',__('Delete'),array( 105 'action' => 'deletePost'))) 106 ->addField( 107 new dcFieldCombo('post_status',$core->auth->getInfo('user_post_status'),$status_combo,array( 108 'disabled' => !$can_publish, 109 'label' => __('Entry status:')))) 110 ->addField( 111 new dcFieldCombo('cat_id','',$categories_combo,array( 112 "label" => __('Category:')))) 113 ->addField( 114 new dcFieldText('post_dt','',array( 115 "label" => __('Published on:')))) 116 ->addField( 117 new dcFieldCombo('post_format',$core->auth->getOption('post_format'),$formaters_combo,array( 118 "label" => __('Text formating:')))) 119 ->addField( 120 new dcFieldCheckbox ('post_open_comment',$core->blog->settings->system->allow_comments,array( 121 "label" => __('Accept comments')))) 122 ->addField( 123 new dcFieldCheckbox ('post_open_tb',$core->blog->settings->system->allow_trackbacks,array( 124 "label" => __('Accept trackbacks')))) 125 ->addField( 126 new dcFieldCheckbox ('post_selected',false,array( 127 "label" => __('Selected entry')))) 128 ->addField( 129 new dcFieldCombo ('post_lang',$core->auth->getInfo('user_lang'),$lang_combo, array( 130 "label" => __('Entry lang:')))) 131 ->addField( 132 new dcFieldHidden ('id','')) 133 ; 93 134 # Get entry informations 94 135 if (!empty($_REQUEST['id'])) … … 105 146 else 106 147 { 107 $post_id = $post->post_id; 108 $cat_id = $post->cat_id; 109 $post_dt = date('Y-m-d H:i',strtotime($post->post_dt)); 110 $post_format = $post->post_format; 111 $post_password = $post->post_password; 112 $post_url = $post->post_url; 113 $post_lang = $post->post_lang; 114 $post_title = $post->post_title; 115 $post_excerpt = $post->post_excerpt; 116 $post_excerpt_xhtml = $post->post_excerpt_xhtml; 117 $post_content = $post->post_content; 118 $post_content_xhtml = $post->post_content_xhtml; 119 $post_notes = $post->post_notes; 120 $post_status = $post->post_status; 121 $post_selected = (boolean) $post->post_selected; 122 $post_open_comment = (boolean) $post->post_open_comment; 123 $post_open_tb = (boolean) $post->post_open_tb; 148 $form->id = $post->post_id; 149 $form->cat_id = $post->cat_id; 150 $form->post_dt = date('Y-m-d H:i',strtotime($post->post_dt)); 151 $form->post_format = $post->post_format; 152 $form->post_password = $post->post_password; 153 $form->post_url = $post->post_url; 154 $form->post_lang = $post->post_lang; 155 $form->post_title = $post->post_title; 156 $form->post_excerpt = $post->post_excerpt; 157 $form->post_excerpt_xhtml = $post->post_excerpt_xhtml; 158 $form->post_content = $post->post_content; 159 $form->post_content_xhtml = $post->post_content_xhtml; 160 $form->post_notes = $post->post_notes; 161 $form->post_status = $post->post_status; 162 $form->post_selected = (boolean) $post->post_selected; 163 $form->post_open_comment = (boolean) $post->post_open_comment; 164 $form->post_open_tb = (boolean) $post->post_open_tb; 165 $form->can_edit_post = $post->isEditable(); 166 $form->can_delete= $post->isDeletable(); 124 167 125 $page_title = __('Edit entry');126 127 $can_edit_post = $post->isEditable();128 $can_delete= $post->isDeletable();129 130 $next_rs = $core->blog->getNextPost($post,1);131 $prev_rs = $core->blog->getNextPost($post,-1);132 133 if ($next_rs !== null) {134 $next_link = sprintf($post_link,$next_rs->post_id,135 html::escapeHTML($next_rs->post_title),__('next entry').' »');136 $next_headlink = sprintf($post_headlink,'next',137 html::escapeHTML($next_rs->post_title),$next_rs->post_id);138 }139 140 if ($prev_rs !== null) {141 $prev_link = sprintf($post_link,$prev_rs->post_id,142 html::escapeHTML($prev_rs->post_title),'« '.__('previous entry'));143 $prev_headlink = sprintf($post_headlink,'previous',144 html::escapeHTML($prev_rs->post_title),$prev_rs->post_id);145 }146 147 try {148 $core->media = new dcMedia($core);149 } catch (Exception $e) {}150 168 } 151 169 } 152 170 153 # Format excerpt and content 154 if (!empty($_POST) && $can_edit_post) 155 { 156 $post_format = $_POST['post_format']; 157 $post_excerpt = $_POST['post_excerpt']; 158 $post_content = $_POST['post_content']; 159 160 $post_title = $_POST['post_title']; 161 162 $cat_id = (integer) $_POST['cat_id']; 163 164 if (isset($_POST['post_status'])) { 165 $post_status = (integer) $_POST['post_status']; 166 } 167 168 if (empty($_POST['post_dt'])) { 169 $post_dt = ''; 170 } else { 171 try 172 { 173 $post_dt = strtotime($_POST['post_dt']); 174 if ($post_dt == false || $post_dt == -1) { 175 $bad_dt = true; 176 throw new Exception(__('Invalid publication date')); 177 } 178 $post_dt = date('Y-m-d H:i',$post_dt); 179 } 180 catch (Exception $e) 181 { 182 $core->error->add($e->getMessage()); 183 } 184 } 185 186 $post_open_comment = !empty($_POST['post_open_comment']); 187 $post_open_tb = !empty($_POST['post_open_tb']); 188 $post_selected = !empty($_POST['post_selected']); 189 $post_lang = $_POST['post_lang']; 190 $post_password = !empty($_POST['post_password']) ? $_POST['post_password'] : null; 191 192 $post_notes = $_POST['post_notes']; 193 194 if (isset($_POST['post_url'])) { 195 $post_url = $_POST['post_url']; 196 } 197 198 $core->blog->setPostContent( 199 $post_id,$post_format,$post_lang, 200 $post_excerpt,$post_excerpt_xhtml,$post_content,$post_content_xhtml 201 ); 202 } 203 204 # Delete post 205 if (!empty($_POST['delete']) && $can_delete) 206 { 207 try { 208 # --BEHAVIOR-- adminBeforePostDelete 209 $core->callBehavior('adminBeforePostDelete',$post_id); 210 $core->blog->delPost($post_id); 211 http::redirect('posts.php'); 212 } catch (Exception $e) { 213 $core->error->add($e->getMessage()); 214 } 215 } 216 217 # Create or update post 218 if (!empty($_POST) && !empty($_POST['save']) && $can_edit_post && !$bad_dt) 219 { 220 $cur = $core->con->openCursor($core->prefix.'post'); 221 222 $cur->post_title = $post_title; 223 $cur->cat_id = ($cat_id ? $cat_id : null); 224 $cur->post_dt = $post_dt ? date('Y-m-d H:i:00',strtotime($post_dt)) : ''; 225 $cur->post_format = $post_format; 226 $cur->post_password = $post_password; 227 $cur->post_lang = $post_lang; 228 $cur->post_title = $post_title; 229 $cur->post_excerpt = $post_excerpt; 230 $cur->post_excerpt_xhtml = $post_excerpt_xhtml; 231 $cur->post_content = $post_content; 232 $cur->post_content_xhtml = $post_content_xhtml; 233 $cur->post_notes = $post_notes; 234 $cur->post_status = $post_status; 235 $cur->post_selected = (integer) $post_selected; 236 $cur->post_open_comment = (integer) $post_open_comment; 237 $cur->post_open_tb = (integer) $post_open_tb; 238 239 if (isset($_POST['post_url'])) { 240 $cur->post_url = $post_url; 241 } 242 243 # Update post 244 if ($post_id) 245 { 246 try 247 { 248 # --BEHAVIOR-- adminBeforePostUpdate 249 $core->callBehavior('adminBeforePostUpdate',$cur,$post_id); 250 251 $core->blog->updPost($post_id,$cur); 252 253 # --BEHAVIOR-- adminAfterPostUpdate 254 $core->callBehavior('adminAfterPostUpdate',$cur,$post_id); 255 256 http::redirect('post.php?id='.$post_id.'&upd=1'); 257 } 258 catch (Exception $e) 259 { 260 $core->error->add($e->getMessage()); 261 } 262 } 263 else 264 { 265 $cur->user_id = $core->auth->userID(); 266 267 try 268 { 269 # --BEHAVIOR-- adminBeforePostCreate 270 $core->callBehavior('adminBeforePostCreate',$cur); 271 272 $return_id = $core->blog->addPost($cur); 273 274 # --BEHAVIOR-- adminAfterPostCreate 275 $core->callBehavior('adminAfterPostCreate',$cur,$return_id); 276 277 http::redirect('post.php?id='.$return_id.'&crea=1'); 278 } 279 catch (Exception $e) 280 { 281 $core->error->add($e->getMessage()); 282 } 283 } 284 } 171 $form->setup(); 285 172 286 173 /* DISPLAY … … 294 181 } 295 182 296 dcPage::open($page_title.' - '.__('Entries'), 297 dcPage::jsDatePicker(). 298 dcPage::jsToolBar(). 299 dcPage::jsModal(). 300 dcPage::jsMetaEditor(). 301 dcPage::jsLoad('js/_post.js'). 302 dcPage::jsConfirmClose('entry-form','comment-form'). 303 # --BEHAVIOR-- adminPostHeaders 304 $core->callBehavior('adminPostHeaders'). 305 dcPage::jsPageTabs($default_tab). 306 $next_headlink."\n".$prev_headlink 307 ); 183 $_ctx 184 ->fillPageTitle(__('Entries'),'posts.php') 185 ->fillPageTitle($page_title) 186 ->default_tab = $default_tab; 308 187 309 if (!empty($_GET['upd'])) { 310 dcPage::message(__('Entry has been successfully updated.')); 311 } 312 elseif (!empty($_GET['crea'])) { 313 dcPage::message(__('Entry has been successfully created.')); 314 } 315 elseif (!empty($_GET['attached'])) { 316 dcPage::message(__('File has been successfully attached.')); 317 } 318 elseif (!empty($_GET['rmattach'])) { 319 dcPage::message(__('Attachment has been successfully removed.')); 320 } 321 322 if (!empty($_GET['creaco'])) { 323 dcPage::message(__('Comment has been successfully created.')); 324 } 325 326 # XHTML conversion 327 if (!empty($_GET['xconv'])) 328 { 329 $post_excerpt = $post_excerpt_xhtml; 330 $post_content = $post_content_xhtml; 331 $post_format = 'xhtml'; 332 333 dcPage::message(__('Don\'t forget to validate your XHTML conversion by saving your post.')); 334 } 335 336 echo '<h2>'.html::escapeHTML($core->blog->name).' › '.'<a href="posts.php">'.__('Entries').'</a> › <span class="page-title">'; 337 if ($post_id) { 338 switch ($post_status) { 339 case 1: 340 $img_status = sprintf($img_status_pattern,__('published'),'check-on.png'); 341 break; 342 case 0: 343 $img_status = sprintf($img_status_pattern,__('unpublished'),'check-off.png'); 344 break; 345 case -1: 346 $img_status = sprintf($img_status_pattern,__('scheduled'),'scheduled.png'); 347 break; 348 case -2: 349 $img_status = sprintf($img_status_pattern,__('pending'),'check-wrn.png'); 350 break; 351 default: 352 $img_status = ''; 353 } 354 $edit_entry_str = __('Edit entry “%s”'); 355 echo sprintf($edit_entry_str, html::escapeHTML($post_title)).' '.$img_status; 356 } else { 357 echo $page_title; 358 } 359 echo '</span></h2>'; 360 361 if ($post_id && $post->post_status == 1) { 362 echo '<p><a href="'.$post->getURL().'" onclick="window.open(this.href);return false;" title="'.$post_title.' ('.__('new window').')'.'">'.__('Go to this entry on the site').' <img src="images/outgoing-blue.png" alt="" /></a></p>'; 363 } 364 if ($post_id) 365 { 366 echo '<p>'; 367 if ($prev_link) { echo $prev_link; } 368 if ($next_link && $prev_link) { echo ' - '; } 369 if ($next_link) { echo $next_link; } 370 371 # --BEHAVIOR-- adminPostNavLinks 372 $core->callBehavior('adminPostNavLinks',isset($post) ? $post : null); 373 374 echo '</p>'; 375 } 376 377 # Exit if we cannot view page 378 if (!$can_view_page) { 379 dcPage::helpBlock('core_post'); 380 dcPage::close(); 381 exit; 382 } 383 384 /* Post form if we can edit post 385 -------------------------------------------------------- */ 386 if ($can_edit_post) 387 { 388 echo '<div class="multi-part" title="'.($post_id ? __('Edit entry') : __('New entry')).'" id="edit-entry">'; 389 echo '<form action="post.php" method="post" id="entry-form">'; 390 echo '<div id="entry-wrapper">'; 391 echo '<div id="entry-content"><div class="constrained">'; 392 393 echo 394 '<p class="col"><label class="required"><abbr title="'.__('Required field').'">*</abbr> '.__('Title:').'</label>'. 395 form::field('post_title',20,255,html::escapeHTML($post_title),'maximal'). 396 '</p>'. 397 398 '<p class="area" id="excerpt-area"><label for="post_excerpt">'.__('Excerpt:').'</label> '. 399 form::textarea('post_excerpt',50,5,html::escapeHTML($post_excerpt)). 400 '</p>'. 401 402 '<p class="area"><label class="required" '. 403 'for="post_content"><abbr title="'.__('Required field').'">*</abbr> '.__('Content:').'</label> '. 404 form::textarea('post_content',50,$core->auth->getOption('edit_size'),html::escapeHTML($post_content)). 405 '</p>'. 406 407 '<p class="area" id="notes-area"><label for="post_notes">'.__('Personal notes:').'</label>'. 408 form::textarea('post_notes',50,5,html::escapeHTML($post_notes)). 409 '</p>'; 410 411 # --BEHAVIOR-- adminPostForm 412 $core->callBehavior('adminPostForm',isset($post) ? $post : null); 413 414 echo 415 '<p>'. 416 ($post_id ? form::hidden('id',$post_id) : ''). 417 '<input type="submit" value="'.__('Save').' (s)" '. 418 'accesskey="s" name="save" /> '; 419 if ($post_id) { 420 $preview_url = 421 $core->blog->url.$core->url->getURLFor('preview',$core->auth->userID().'/'. 422 http::browserUID(DC_MASTER_KEY.$core->auth->userID().$core->auth->getInfo('user_pwd')). 423 '/'.$post->post_url); 424 echo '<a id="post-preview" href="'.$preview_url.'" class="button" accesskey="p">'.__('Preview').' (p)'.'</a> '; 425 } else { 426 echo 427 '<a id="post-cancel" href="index.php" class="button" accesskey="c">'.__('Cancel').' (c)</a>'; 428 } 429 430 echo 431 ($can_delete ? '<input type="submit" class="delete" value="'.__('Delete').'" name="delete" />' : ''). 432 $core->formNonce(). 433 '</p>'; 434 435 echo '</div></div>'; // End #entry-content 436 echo '</div>'; // End #entry-wrapper 437 438 echo '<div id="entry-sidebar">'; 439 440 echo 441 '<p><label for="cat_id">'.__('Category:'). 442 form::combo('cat_id',$categories_combo,$cat_id,'maximal'). 443 '</label></p>'. 444 445 '<p><label for="post_status">'.__('Entry status:'). 446 form::combo('post_status',$status_combo,$post_status,'','',!$can_publish). 447 '</label></p>'. 448 449 '<p><label for="post_dt">'.__('Published on:'). 450 form::field('post_dt',16,16,$post_dt,($bad_dt ? 'invalid' : '')). 451 '</label></p>'. 452 453 '<p><label for="post_format">'.__('Text formating:'). 454 form::combo('post_format',$formaters_combo,$post_format). 455 '</label>'. 456 '</p>'. 457 '<p>'.($post_id && $post_format != 'xhtml' ? '<a id="convert-xhtml" class="button" href="post.php?id='.$post_id.'&xconv=1">'.__('Convert to XHTML').'</a>' : '').'</p>'. 458 459 '<p><label for="post_open_comment" class="classic">'.form::checkbox('post_open_comment',1,$post_open_comment).' '. 460 __('Accept comments').'</label></p>'. 461 ($core->blog->settings->system->allow_comments ? 462 (isContributionAllowed($post_id,strtotime($post_dt),true) ? 463 '' : 464 '<p class="form-note warn">'.__('Warning: Comments are not more accepted for this entry.').'</p>') : 465 '<p class="form-note warn">'.__('Warning: Comments are not accepted on this blog.').'</p>'). 466 467 '<p><label for="post_open_tb" class="classic">'.form::checkbox('post_open_tb',1,$post_open_tb).' '. 468 __('Accept trackbacks').'</label></p>'. 469 ($core->blog->settings->system->allow_trackbacks ? 470 (isContributionAllowed($post_id,strtotime($post_dt),false) ? 471 '' : 472 '<p class="form-note warn">'.__('Warning: Trackbacks are not more accepted for this entry.').'</p>') : 473 '<p class="form-note warn">'.__('Warning: Trackbacks are not accepted on this blog.').'</p>'). 474 475 '<p><label for="post_selected" class="classic">'.form::checkbox('post_selected',1,$post_selected).' '. 476 __('Selected entry').'</label></p>'. 477 478 '<p><label for="post_lang">'.__('Entry lang:'). 479 form::combo('post_lang',$lang_combo,$post_lang). 480 '</label></p>'. 481 482 '<p><label for="post_password">'.__('Entry password:'). 483 form::field('post_password',10,32,html::escapeHTML($post_password),'maximal'). 484 '</label></p>'. 485 486 '<div class="lockable">'. 487 '<p><label for="post_url">'.__('Basename:'). 488 form::field('post_url',10,255,html::escapeHTML($post_url),'maximal'). 489 '</label></p>'. 490 '<p class="form-note warn">'. 491 __('Warning: If you set the URL manually, it may conflict with another entry.'). 492 '</p>'. 493 '</div>'; 494 495 # --BEHAVIOR-- adminPostFormSidebar 496 $core->callBehavior('adminPostFormSidebar',isset($post) ? $post : null); 497 498 echo '</div>'; // End #entry-sidebar 499 500 echo '</form>'; 501 502 # --BEHAVIOR-- adminPostForm 503 $core->callBehavior('adminPostAfterForm',isset($post) ? $post : null); 504 505 echo '</div>'; 506 507 if ($post_id && $post->post_status == 1) { 508 echo '<p><a href="trackbacks.php?id='.$post_id.'" class="multi-part">'. 509 __('Ping blogs').'</a></p>'; 510 } 511 512 } 513 514 515 /* Comments and trackbacks 516 -------------------------------------------------------- */ 517 if ($post_id) 518 { 519 $params = array('post_id' => $post_id, 'order' => 'comment_dt ASC'); 520 521 $comments = $core->blog->getComments(array_merge($params,array('comment_trackback'=>0))); 522 $trackbacks = $core->blog->getComments(array_merge($params,array('comment_trackback'=>1))); 523 524 # Actions combo box 525 $combo_action = array(); 526 if ($can_edit_post && $core->auth->check('publish,contentadmin',$core->blog->id)) 527 { 528 $combo_action[__('publish')] = 'publish'; 529 $combo_action[__('unpublish')] = 'unpublish'; 530 $combo_action[__('mark as pending')] = 'pending'; 531 $combo_action[__('mark as junk')] = 'junk'; 532 } 533 534 if ($can_edit_post && $core->auth->check('delete,contentadmin',$core->blog->id)) 535 { 536 $combo_action[__('Delete')] = 'delete'; 537 } 538 539 # --BEHAVIOR-- adminCommentsActionsCombo 540 $core->callBehavior('adminCommentsActionsCombo',array(&$combo_action)); 541 542 $has_action = !empty($combo_action) && (!$trackbacks->isEmpty() || !$comments->isEmpty()); 543 544 echo 545 '<div id="comments" class="multi-part" title="'.__('Comments').'">'; 546 547 if ($has_action) { 548 echo '<form action="comments_actions.php" id="form-comments" method="post">'; 549 } 550 551 echo '<h3>'.__('Trackbacks').'</h3>'; 552 553 if (!$trackbacks->isEmpty()) { 554 showComments($trackbacks,$has_action,true); 555 } else { 556 echo '<p>'.__('No trackback').'</p>'; 557 } 558 559 echo '<h3>'.__('Comments').'</h3>'; 560 if (!$comments->isEmpty()) { 561 showComments($comments,$has_action); 562 } else { 563 echo '<p>'.__('No comment').'</p>'; 564 } 565 566 if ($has_action) { 567 echo 568 '<div class="two-cols">'. 569 '<p class="col checkboxes-helpers"></p>'. 570 571 '<p class="col right"><label for="action" class="classic">'.__('Selected comments action:').'</label> '. 572 form::combo('action',$combo_action). 573 form::hidden('redir','post.php?id='.$post_id.'&co=1'). 574 $core->formNonce(). 575 '<input type="submit" value="'.__('ok').'" /></p>'. 576 '</div>'. 577 '</form>'; 578 } 579 580 echo '</div>'; 581 } 582 583 /* Add a comment 584 -------------------------------------------------------- */ 585 if ($post_id) 586 { 587 echo 588 '<div class="multi-part" id="add-comment" title="'.__('Add a comment').'">'. 589 '<h3>'.__('Add a comment').'</h3>'. 590 591 '<form action="comment.php" method="post" id="comment-form">'. 592 '<div class="constrained">'. 593 '<p><label for="comment_author" class="required"><abbr title="'.__('Required field').'">*</abbr> '.__('Name:'). 594 form::field('comment_author',30,255,html::escapeHTML($core->auth->getInfo('user_cn'))). 595 '</label></p>'. 596 597 '<p><label for="comment_email">'.__('Email:'). 598 form::field('comment_email',30,255,html::escapeHTML($core->auth->getInfo('user_email'))). 599 '</label></p>'. 600 601 '<p><label for="comment_site">'.__('Web site:'). 602 form::field('comment_site',30,255,html::escapeHTML($core->auth->getInfo('user_url'))). 603 '</label></p>'. 604 605 '<p class="area"><label for="comment_content" class="required"><abbr title="'.__('Required field').'">*</abbr> '. 606 __('Comment:').'</label> '. 607 form::textarea('comment_content',50,8,html::escapeHTML('')). 608 '</p>'. 609 610 '<p>'.form::hidden('post_id',$post_id). 611 $core->formNonce(). 612 '<input type="submit" name="add" value="'.__('Save').'" /></p>'. 613 '</div>'. 614 '</form>'. 615 '</div>'; 616 } 617 618 # Controls comments or trakbacks capabilities 619 function isContributionAllowed($id,$dt,$com=true) 620 { 621 global $core; 622 623 if (!$id) { 624 return true; 625 } 626 if ($com) { 627 if (($core->blog->settings->system->comments_ttl == 0) || 628 (time() - $core->blog->settings->system->comments_ttl*86400 < $dt)) { 629 return true; 630 } 631 } else { 632 if (($core->blog->settings->system->trackbacks_ttl == 0) || 633 (time() - $core->blog->settings->system->trackbacks_ttl*86400 < $dt)) { 634 return true; 635 } 636 } 637 return false; 638 } 639 640 # Show comments or trackbacks 641 function showComments($rs,$has_action,$tb=false) 642 { 643 echo 644 '<table class="comments-list"><tr>'. 645 '<th colspan="2">'.__('Author').'</th>'. 646 '<th>'.__('Date').'</th>'. 647 '<th class="nowrap">'.__('IP address').'</th>'. 648 '<th>'.__('Status').'</th>'. 649 '<th> </th>'. 650 '</tr>'; 651 652 while($rs->fetch()) 653 { 654 $comment_url = 'comment.php?id='.$rs->comment_id; 655 656 $img = '<img alt="%1$s" title="%1$s" src="images/%2$s" />'; 657 switch ($rs->comment_status) { 658 case 1: 659 $img_status = sprintf($img,__('published'),'check-on.png'); 660 break; 661 case 0: 662 $img_status = sprintf($img,__('unpublished'),'check-off.png'); 663 break; 664 case -1: 665 $img_status = sprintf($img,__('pending'),'check-wrn.png'); 666 break; 667 case -2: 668 $img_status = sprintf($img,__('junk'),'junk.png'); 669 break; 670 } 671 672 echo 673 '<tr class="line'.($rs->comment_status != 1 ? ' offline' : '').'"'. 674 ' id="c'.$rs->comment_id.'">'. 675 676 '<td class="nowrap">'. 677 ($has_action ? form::checkbox(array('comments[]'),$rs->comment_id,'','','',0,'title="'.($tb ? __('select this trackback') : __('select this comment')).'"') : '').'</td>'. 678 '<td class="maximal">'.html::escapeHTML($rs->comment_author).'</td>'. 679 '<td class="nowrap">'.dt::dt2str(__('%Y-%m-%d %H:%M'),$rs->comment_dt).'</td>'. 680 '<td class="nowrap"><a href="comments.php?ip='.$rs->comment_ip.'">'.$rs->comment_ip.'</a></td>'. 681 '<td class="nowrap status">'.$img_status.'</td>'. 682 '<td class="nowrap status"><a href="'.$comment_url.'">'. 683 '<img src="images/edit-mini.png" alt="" title="'.__('Edit this comment').'" /></a></td>'. 684 685 '</tr>'; 686 } 687 688 echo '</table>'; 689 } 690 691 dcPage::helpBlock('core_post','core_wiki'); 692 dcPage::close(); 188 $core->tpl->display('post.html.twig'); 693 189 ?> -
admin/posts.php
r1179 r1315 4 4 # This file is part of Dotclear 2. 5 5 # 6 # Copyright (c) 2003-201 3Olivier Meunier & Association Dotclear6 # Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 12 12 13 13 require dirname(__FILE__).'/../inc/admin/prepend.php'; 14 14 global $_ctx; 15 15 dcPage::check('usage,contentadmin'); 16 16 … … 48 48 # Filter form we'll put in html_block 49 49 $users_combo = $categories_combo = array(); 50 $users_combo['-'] = $categories_combo['-'] = '';51 50 while ($users->fetch()) 52 51 { … … 61 60 } 62 61 63 $categories_combo[__('None')] = 'NULL'; 62 63 # Getting categories 64 $categories_combo = array(); 65 try { 66 $categories = $core->blog->getCategories(array('post_type'=>'post')); 64 67 while ($categories->fetch()) { 65 $categories_combo[str_repeat(' ',$categories->level-1).($categories->level-1 == 0 ? '' : '• '). 66 html::escapeHTML($categories->cat_title). 67 ' ('.$categories->nb_post.')'] = $categories->cat_id; 68 $categories_combo[$categories->cat_id] = 69 str_repeat(' ',$categories->level-1). 70 ($categories->level-1 == 0 ? '' : '• '). 71 html::escapeHTML($categories->cat_title); 68 72 } 69 73 } catch (Exception $e) { } 70 74 $status_combo = array( 71 '-' => ''72 75 ); 73 76 foreach ($core->blog->getAllPostStatus() as $k => $v) { 74 $status_combo[ $v] = (string) $k;77 $status_combo[(string) $k] = (string)$v; 75 78 } 76 79 77 80 $selected_combo = array( 78 '-' => '', 79 __('selected') => '1', 80 __('not selected') => '0' 81 '1' => __('is selected'), 82 '0' => __('is not selected') 81 83 ); 82 84 83 85 # Months array 84 $dt_m_combo['-'] = '';85 86 while ($dates->fetch()) { 86 $dt_m_combo[ dt::str('%B %Y',$dates->ts())] = $dates->year().$dates->month();87 $dt_m_combo[$dates->year().$dates->month()] = dt::str('%B %Y',$dates->ts()); 87 88 } 88 89 89 $lang_combo['-'] = '';90 90 while ($langs->fetch()) { 91 91 $lang_combo[$langs->post_lang] = $langs->post_lang; 92 92 } 93 94 $sortby_combo = array(95 __('Date') => 'post_dt',96 __('Title') => 'post_title',97 __('Category') => 'cat_title',98 __('Author') => 'user_id',99 __('Status') => 'post_status',100 __('Selected') => 'post_selected'101 );102 103 $order_combo = array(104 __('Descending') => 'desc',105 __('Ascending') => 'asc'106 );107 93 } 94 $form = new dcForm($core,'post','post.php'); 95 108 96 109 97 # Actions combo box … … 138 126 $core->callBehavior('adminPostsActionsCombo',array(&$combo_action)); 139 127 140 /* Get posts141 -------------------------------------------------------- */142 $user_id = !empty($_GET['user_id']) ? $_GET['user_id'] : '';143 $cat_id = !empty($_GET['cat_id']) ? $_GET['cat_id'] : '';144 $status = isset($_GET['status']) ? $_GET['status'] : '';145 $selected = isset($_GET['selected']) ? $_GET['selected'] : '';146 $month = !empty($_GET['month']) ? $_GET['month'] : '';147 $lang = !empty($_GET['lang']) ? $_GET['lang'] : '';148 $sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'post_dt';149 $order = !empty($_GET['order']) ? $_GET['order'] : 'desc';150 128 151 $show_filters = false;152 129 153 $page = !empty($_GET['page']) ? (integer) $_GET['page'] : 1; 154 $nb_per_page = 30; 155 156 if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) { 157 if ($nb_per_page != $_GET['nb']) { 158 $show_filters = true; 130 class monthdcFilterCombo extends dcFilterCombo { 131 public function applyFilter($params) { 132 $month=$this->avalues['values'][0]; 133 $params['post_month'] = substr($month,4,2); 134 $params['post_year'] = substr($month,0,4); 159 135 } 160 $nb_per_page = (integer) $_GET['nb'];161 136 } 162 137 163 $params['limit'] = array((($page-1)*$nb_per_page),$nb_per_page); 164 $params['no_content'] = true; 138 class PostsFetcher extends dcListFetcher { 165 139 166 # - User filter 167 if ($user_id !== '' && in_array($user_id,$users_combo)) { 168 $params['user_id'] = $user_id; 169 $show_filters = true; 170 } else { 171 $user_id=''; 172 } 140 public function getEntries($params,$offset,$limit) { 141 $params['limit'] = array($offset,$limit); 142 return $this->core->blog->getPosts($params); 143 } 173 144 174 # - Categories filter 175 if ($cat_id !== '' && in_array($cat_id,$categories_combo)) { 176 $params['cat_id'] = $cat_id; 177 $show_filters = true; 178 } else { 179 $cat_id=''; 180 } 181 182 # - Status filter 183 if ($status !== '' && in_array($status,$status_combo)) { 184 $params['post_status'] = $status; 185 $show_filters = true; 186 } else { 187 $status=''; 188 } 189 190 # - Selected filter 191 if ($selected !== '' && in_array($selected,$selected_combo)) { 192 $params['post_selected'] = $selected; 193 $show_filters = true; 194 } else { 195 $selected=''; 196 } 197 198 # - Month filter 199 if ($month !== '' && in_array($month,$dt_m_combo)) { 200 $params['post_month'] = substr($month,4,2); 201 $params['post_year'] = substr($month,0,4); 202 $show_filters = true; 203 } else { 204 $month=''; 205 } 206 207 # - Lang filter 208 if ($lang !== '' && in_array($lang,$lang_combo)) { 209 $params['post_lang'] = $lang; 210 $show_filters = true; 211 } else { 212 $lang=''; 213 } 214 215 # - Sortby and order filter 216 if ($sortby !== '' && in_array($sortby,$sortby_combo)) { 217 if ($order !== '' && in_array($order,$order_combo)) { 218 $params['order'] = $sortby.' '.$order; 219 } else { 220 $order='desc'; 145 public function getEntriesCount($params) { 146 $count = $this->core->blog->getPosts($params,true); 147 return $count->f(0); 221 148 } 222 223 if ($sortby != 'post_dt' || $order != 'desc') {224 $show_filters = true;225 }226 } else {227 $sortby='post_dt';228 $order='desc';229 }230 231 # Get posts232 try {233 $posts = $core->blog->getPosts($params);234 $counter = $core->blog->getPosts($params,true);235 $post_list = new adminPostList($core,$posts,$counter->f(0));236 } catch (Exception $e) {237 $core->error->add($e->getMessage());238 149 } 239 150 240 151 /* DISPLAY 241 152 -------------------------------------------------------- */ 242 $starting_script = dcPage::jsLoad('js/_posts_list.js'); 243 if (!$show_filters) { 244 $starting_script .= dcPage::jsLoad('js/filter-controls.js'); 245 } 153 $filterSet = new dcFilterSet($core,'fposts','posts.php'); 246 154 247 dcPage::open(__('Entries'),$starting_script); 155 $filterSet 156 ->addFilter(new dcFilterRichCombo( 157 'users',__('Author'), __('Author'), 'user_id', $users_combo,array( 158 'multiple' => true))) 159 ->addFilter(new dcFilterRichCombo( 160 'category',__('Category'), __('Category'), 'cat_id', $categories_combo)) 161 ->addFilter(new dcFilterRichCombo( 162 'post_status',__('Status'), __('Status'), 'post_status', $status_combo)) 163 ->addFilter(new dcFilterRichCombo( 164 'lang',__('Lang'), __('Lang'), 'post_lang', $lang_combo)) 165 ->addFilter(new dcFilterCombo( 166 'selected',__('Selected'), __('The post : '),'post_selected', $selected_combo)) 167 ->addFilter(new monthdcFilterCombo( 168 'month',__('Month'),__('Month'), 'post_month', $dt_m_combo,array('singleval' => 1))) 169 ->addFilter(new dcFilterText( 170 'search',__('Contains'),__('The entry contains'), 'search',20,255)); 248 171 249 if (!$core->error->flag())250 {251 echo252 '<h2>'.html::escapeHTML($core->blog->name).' › <span class="page-title">'.__('Entries').'</span></h2>'.253 '<p class="top-add"><a class="button add" href="post.php">'.__('New entry').'</a></p>';254 255 if (!$show_filters) {256 echo '<p><a id="filter-control" class="form-control" href="#">'.257 __('Filters').'</a></p>';258 }259 260 echo261 '<form action="posts.php" method="get" id="filters-form">'.262 '<fieldset><legend>'.__('Filters').'</legend>'.263 '<div class="three-cols">'.264 '<div class="col">'.265 '<label for="user_id">'.__('Author:').266 form::combo('user_id',$users_combo,$user_id).'</label> '.267 '<label for="cat_id">'.__('Category:').268 form::combo('cat_id',$categories_combo,$cat_id).'</label> '.269 '<label for="status">'.__('Status:').270 form::combo('status',$status_combo,$status).'</label> '.271 '</div>'.272 273 '<div class="col">'.274 '<label for="selected">'.__('Selected:').275 form::combo('selected',$selected_combo,$selected).'</label> '.276 '<label for="month">'.__('Month:').277 form::combo('month',$dt_m_combo,$month).'</label> '.278 '<label for="lang">'.__('Lang:').279 form::combo('lang',$lang_combo,$lang).'</label> '.280 '</div>'.281 282 '<div class="col">'.283 '<p><label for="sortby">'.__('Order by:').284 form::combo('sortby',$sortby_combo,$sortby).'</label> '.285 '<label for="order">'.__('Sort:').286 form::combo('order',$order_combo,$order).'</label></p>'.287 '<p><label for="nb" class="classic">'. form::field('nb',3,3,$nb_per_page).' '.288 __('Entries per page').'</label></p> '.289 '<p><input type="submit" value="'.__('Apply filters').'" /></p>'.290 '</div>'.291 '</div>'.292 '<br class="clear" />'. //Opera sucks293 '</fieldset>'.294 '</form>';295 296 # Show posts297 $post_list->display($page,$nb_per_page,298 '<form action="posts_actions.php" method="post" id="form-entries">'.299 300 '%s'.301 302 '<div class="two-cols">'.303 '<p class="col checkboxes-helpers"></p>'.304 305 '<p class="col right"><label for="action" class="classic">'.__('Selected entries action:').'</label> '.306 form::combo('action',$combo_action).307 '<input type="submit" value="'.__('ok').'" /></p>'.308 form::hidden(array('user_id'),$user_id).309 form::hidden(array('cat_id'),$cat_id).310 form::hidden(array('status'),$status).311 form::hidden(array('selected'),$selected).312 form::hidden(array('month'),$month).313 form::hidden(array('lang'),$lang).314 form::hidden(array('sortby'),$sortby).315 form::hidden(array('order'),$order).316 form::hidden(array('page'),$page).317 form::hidden(array('nb'),$nb_per_page).318 $core->formNonce().319 '</div>'.320 '</form>'321 );322 }323 172 324 dcPage::helpBlock('core_posts'); 325 dcPage::close(); 173 $lfetcher = new PostsFetcher($core); 174 $lposts = new dcItemList ($core,array('lposts','form-entries'),$filterSet,$lfetcher,'posts_actions.php'); 175 $lposts->addTemplate('posts_cols.html.twig'); 176 177 $lposts 178 ->addColumn(new dcColumn('title',__('Title'),'post_title')) 179 ->addColumn(new dcColumn('cat',__('Category'),'cat_title')) 180 ->addColumn(new dcColumn('date',__('Date'),'post_date')) 181 ->addColumn(new dcColumn('datetime',__('Date and Time'),'post_dt')) 182 ->addColumn(new dcColumn('author',__('Author'),'user_id')) 183 ->addColumn(new dcColumn('status',__('Status'),'post_status')); 184 185 186 $lposts->setup(); 187 188 $_ctx 189 ->fillPageTitle(__('Entries'),'posts.php'); 190 191 192 $core->tpl->display('posts.html.twig'); 193 194 326 195 ?> -
admin/style/default.css
r1155 r1315 4 4 # This file is part of Dotclear 2. 5 5 # 6 # Copyright (c) 2003-201 1Olivier Meunier & Association Dotclear6 # Copyright (c) 2003-2013 Olivier Meunier & Association Dotclear 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 13 13 14 14 /* ------------------------------------------------------------------ html */ 15 html { 16 font-size: 62.5%; 17 } 15 18 body { 16 font: 75%/1.5emHelvetica,Arial,sans-serif;19 font: 1.2rem/1.5 Helvetica,Arial,sans-serif; 17 20 color: #333; 18 background: #f5f5f5;19 margin: 0;20 padding: 0;21 }22 body.auth {23 21 background: #fff; 22 margin: 0; 23 padding: 0; 24 24 } 25 25 … … 38 38 h1, h2, h3, h4, h5, h6, p { 39 39 margin-top: 0; 40 margin-bottom: 0.6em; 41 } 42 40 margin-bottom: 1rem; 41 } 43 42 h2 { 44 43 color: #666; 45 font-size: 1.4em; 46 padding: 4px 0; 44 font-size: 1.8rem; 45 padding: 0 0 1.8rem; 46 font-weight: normal; 47 } 48 h2 a:link, h2 a:visited { 49 color: #666; 50 border-color: #000; 47 51 } 48 52 .page-title { 49 53 color: #d30e60; 50 54 } 55 #content > h2 { 56 padding: 0 1.8rem .6rem; 57 margin: 0 -1.8rem 1rem; 58 background: #fff url(dc_bg_title.png) repeat-x center bottom; 59 } 51 60 h3 { 52 color: #333; 53 font-size: 1.2em; 54 } 55 61 color: #575859; 62 font-size: 1.4rem; 63 } 56 64 p, div.p { 57 65 margin: 0 0 1em 0; 58 66 } 59 60 67 hr { 61 68 height: 1px; 62 border-width: 1px 0 0 0;69 border-width: 1px 0 0; 63 70 border-color: #999; 64 71 border-style: solid; 65 72 } 66 67 73 pre, code { 68 74 font: 100% "Andale Mono","Courier New",monospace; … … 82 88 } 83 89 84 85 90 /* LAYOUT 86 91 -------------------------------------------------------- */ … … 90 95 height: 3em; 91 96 position: relative; 97 border-bottom: 4px solid #A2CBE9; 92 98 } 93 99 #prelude { 94 background: #575859; 95 line-height: 1.5em; 96 margin: 0; 97 padding: 0 1.7em 0 1em; 100 line-height: 1.9; 101 margin: 0; 102 padding: 0; 98 103 overflow: hidden; 99 104 position: absolute; 100 top: 1.2em;105 top: 3em; 101 106 left: 0; 107 background: #A2CBE9; 108 width: 14.5em; 102 109 } 103 110 #prelude li { 104 111 list-style-type: none; 105 margin: 0 1em 0 0;112 margin: 0; 106 113 background:transparent; 107 114 } 108 115 #prelude li a { 109 color:#fff; 110 } 116 padding-left: 1.6rem; 117 background: #A2CBE9; 118 color: #000; 119 border-bottom-color: #A2CBE9; 120 } 111 121 #top { 112 122 margin: 0; 113 123 padding: 0; 114 width: 1 3em;124 width: 14.5em; 115 125 float: left; 126 line-height: 3em; 116 127 } 117 128 #top h1 { 118 129 padding: 0; 119 130 margin: 0; 120 height: 3 em;131 height: 3.6rem; 121 132 text-indent: -1000px; 122 background: transparenturl(dc_logo.png) no-repeat 0 50%;133 background: #575859 url(dc_logo.png) no-repeat 0 50%; 123 134 } 124 135 #top h1 a { 125 136 position: absolute; 126 top: 3px;137 top: 0; 127 138 left: 0; 128 width: 1 30px;129 height: 60px;139 width: 14.5em; 140 height: 3.6rem; 130 141 border: none; 131 outline: none;132 142 color: #fff; 143 } 144 #top h1 a:hover, #top h1 a:focus { 145 background: transparent url(dc_logo_hover.png) no-repeat 0 50%; 133 146 } 134 147 #info-boxes { 135 148 background: #575859; 136 font-size: .95em;137 height: 3em;149 font-size: 1em; 150 line-height: 3em; 138 151 } 139 152 #info-box1 { 140 153 margin: 0; 141 padding: .5em 3px 4px 0;154 padding: 0 3px 0 1.8rem; 142 155 color: #fff; 143 float: left;156 display: inline-block; 144 157 background: #575859; 145 158 } 146 159 #info-box2 { 147 margin: .1em 0 00;148 padding: .5em 1.3em 4px0;160 margin: 0; 161 padding: 0 1.3em 0 0; 149 162 color: #fff; 150 163 float: right; 151 164 text-align: right; 152 165 background: #575859; 153 height: 2em;154 166 } 155 167 #info-box1 p { … … 158 170 } 159 171 #info-box1 select { 160 width: 1 5em;172 width: 14.5em; 161 173 } 162 174 #info-box1 a img, #info-box2 a img { … … 164 176 padding-left: .3em; 165 177 } 166 #info-box 1 a, #info-box2a {178 #info-boxes a { 167 179 background: #575859; 168 180 font-weight: bold; … … 178 190 } 179 191 #info-box2 a.active { 180 border-bottom-color: #f 5f5f5;192 border-bottom-color: #fff; 181 193 margin: 0; 182 194 padding: 1.2em .5em; 183 background-color: #f 5f5f5;195 background-color: #fff; 184 196 color: #333; 185 197 font-weight: bold; 186 198 } 187 199 #info-box2 span { 188 color: # 575859;189 } 190 /* prelude*/200 color: #999; 201 } 202 /* main blocks */ 191 203 #wrapper { 192 204 width: 100%; … … 195 207 width: 100%; 196 208 float: right; 197 margin-left: -1 3em;209 margin-left: -14.5em; 198 210 margin-top: 0; 211 background: #fff url(dc_bg.png); 199 212 } 200 213 #content { 201 margin: 1.5em 1.5em .5em 13em;202 padding: 1em;214 margin: 0 0 0 14.5em; 215 padding: .9rem 1.8rem 1.8rem; 203 216 background: #fff; 204 border-radius: .5em;205 border: 1px solid #ddd;206 217 } 207 218 /* Micro clearfix thx to Nicolas Gallagher */ … … 244 255 /* -------------------------------------------------------------- layout - onglets */ 245 256 .part-tabs ul { 246 padding: . 3em 0 1px1em;247 border-bottom: 1px solid # 999;257 padding: .5em 0 .3em 1em; 258 border-bottom: 1px solid #ccc; 248 259 } 249 260 .part-tabs li { … … 253 264 } 254 265 .part-tabs li a { 255 padding: . 3em 0.5em;266 padding: .5em 0.5em; 256 267 margin-right: .5em; 257 border: 1px solid # 999;268 border: 1px solid #ccc; 258 269 border-bottom: none; 259 270 background: #dfdfdf; 260 271 text-decoration: none; 261 border-top-left-radius: .3em;262 border-top-right-radius: .3em;263 272 color: #000; 273 background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #dfdfdf), color-stop(1, #fafafa) ); 274 background:-moz-linear-gradient( center top, #dfdfdf 5%, #fafafa 100% ); 275 filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#dfdfdf', endColorstr='#fafafa'); 276 background-color:#ededed; 264 277 } 265 278 .part-tabs li.part-tabs-link a { … … 273 286 .part-tabs li.part-tabs-active a { 274 287 background: #fff; 275 border -bottom: 1px solid #fff;276 color: # 000;288 border: 1px solid #d30e60; 289 color: #d30e60; 277 290 font-weight: bold; 291 border-bottom-color: #fff; 278 292 } 279 293 /* ------------------------------------------------------------------ main-menu */ 280 294 #main-menu { 281 width: 1 3em;295 width: 14.5em; 282 296 float: left; 283 margin-top: 1.2em; 284 margin-bottom: .5em; 297 margin:0; 298 padding-top: .5em; 299 padding-bottom: 1em; 300 background: #f7f7f7; 285 301 } 286 302 #main-menu h3 { 287 margin: 0 0 0.5em;288 padding: .5em 0 0 .5em;289 text- transform: uppercase;303 margin: 0; 304 padding: 1.2rem 0 1rem 2.2rem; 305 text-indent: -1.6rem; 290 306 color: #666; 291 font-size: 1.1em; 307 font-size: 1.4rem; 308 } 309 #main-menu h3 img[alt="cacher"] { 310 vertical-align: top; 292 311 } 293 312 #main-menu ul { 294 font-size: .95em; 295 margin: 0 0 1em 0; 313 margin: 0 0 1.8rem 0; 296 314 padding: 0; 297 315 list-style: none; … … 300 318 display: block; 301 319 margin: 0.5em 0 0; 302 padding: . 2em 0 0 32px;320 padding: .3rem 0 0 30px; 303 321 background-repeat: no-repeat; 304 background-position: 12px .4em;322 background-position: 8px .3em; 305 323 } 306 324 #main-menu a { 307 font-weight: bold; 325 color: #333; 326 border-bottom-color: #ccc; 308 327 } 309 328 #main-menu .active a { 310 329 border-bottom: none; 311 color: # 333;330 color: #d30e60; 312 331 } 313 332 #main-menu .active { 314 background-color: #fff; 315 padding: .4em 0 .1em 32px; 316 background-position: 12px .4em; 317 border-top: 1px solid #ddd; 318 border-bottom: 1px solid #ddd; 319 margin-right: -1px; 320 } 321 #favorites-menu { 322 margin: 0 0 2em; 333 font-weight: bolder; 334 } 335 #search-menu { 336 padding: .3rem .4rem 0; 337 } 338 #search-menu p { 339 display: inline-block; 340 } 341 #search-menu #q { 342 width: 12rem; 343 border-bottom-left-radius: .6em; 344 border-top-left-radius: .6em; 345 border-color: #999; 346 background: transparent url(search.png) no-repeat 4px center; 347 text-indent: 18px; 348 height: 2rem; 349 padding: 0 2px; 350 } 351 #search-menu input[type="submit"] { 352 padding: .1rem .3rem; 353 background: #dfdfdf; 354 border-color: #999; 355 color: #666; 356 border-bottom-right-radius: .6em; 357 border-top-right-radius: .6em; 358 text-shadow: none; 359 height: 2.2rem; 360 font-size: 1rem; 361 margin-left: -.5em; 362 } 363 #search-menu input[type="submit"]:hover, 364 #search-menu input[type="submit"]:focus { 365 background: #575859; 366 color: #fff; 367 } 368 #favorites-menu, #blog-menu, #system-menu, #plugins-menu { 369 border-bottom: 1px dashed #A2CBE9; 323 370 } 324 371 #favorites-menu h3 { 325 color: # 333;326 text-transform: none;372 color: #000; 373 font-variant: small-caps; 327 374 } 328 375 #favorites-menu a { 329 376 color: #333; 330 }331 #favorites-menu .active {332 background-color: transparent;333 border: none;334 }335 #favorites-menu .active a {336 font-weight: bold;337 color: #666;338 377 } 339 378 /* ------------------------------------------------------------------ footer */ 340 379 #footer { 341 380 clear: both; 342 padding: . 75em .75em 00;381 padding: .6rem 1.2rem .6rem 0; 343 382 text-align: right; 383 border-top: .1rem solid #ccc; 344 384 } 345 385 #footer p { … … 347 387 padding: 0 1em; 348 388 text-align: center; 349 font-size: 1 .1em;389 font-size: 1em; 350 390 } 351 391 #footer a { 352 392 } 353 393 #footer p span.credit { 354 font-size: .85em;394 font-size: 1rem; 355 395 font-weight: normal; 356 396 } … … 360 400 width: 18em; 361 401 margin: 1.5em auto 0; 362 font-size: 1. 1em;402 font-size: 1.4rem; 363 403 } 364 404 #login-screen h1 { … … 367 407 height: 50px; 368 408 margin-bottom: .5em; 369 margin-left: .5em;409 margin-left: 0; 370 410 } 371 411 #login-screen fieldset, #login-screen .fieldset { 372 border: 1px solid # 999;412 border: 1px solid #A8DC26; 373 413 padding: 1em 1em 0 1em; 374 414 border-radius: 4px; 375 415 } 416 #login-screen legend { 417 border: 1px solid #A8DC26; 418 } 376 419 #login-screen input[type=text], #login-screen input[type=password], #login-screen input[type=submit] { 377 420 width: 100%; 378 421 } 379 422 #login-screen #issue { 380 margin-left: 1 em;381 font-size: 1 em;423 margin-left: 1.5rem; 424 font-size: 1.2rem; 382 425 } 383 426 #login-screen #issue strong {font-weight: normal;} … … 404 447 width: 210px; 405 448 text-align: center; 406 margin: 2em 0 0 0;449 margin: 2em 0; 407 450 display:inline-block; 408 451 } … … 436 479 color: #666; 437 480 } 438 439 481 #dashboard-items { 440 482 float: left; … … 482 524 } 483 525 #entry-content { 484 margin-right: 18em; 526 margin-right: 19em; 527 margin-left: 1.2rem; 485 528 } 486 529 #entry-sidebar { … … 542 585 height: 500px; 543 586 } 544 545 587 #add-file-f { 546 588 position: relative; … … 626 668 display: inline; 627 669 } 628 629 670 #default-favs h3 { 630 671 margin-top: 2em; 631 672 margin-bottom: 1em; 632 673 } 633 634 674 .fav-list { 635 675 list-style-type: none; … … 785 825 /* ------------------------------------------------------------------ contextual help */ 786 826 #help { 787 margin-top: 2em;827 margin-top: 4em; 788 828 background: #f5f5f5; 789 829 z-index: 100; 790 830 } 791 831 #help-button { 792 position: fixed; 793 top: 3.2em; 832 background: transparent url(../images/page_help.png) no-repeat 6px center; 833 position: absolute; 834 top: 3.6rem; 794 835 right: 0px; 836 padding: 0 2rem 0 3rem; 795 837 cursor: pointer; 796 background: #fc3; 797 border: 1px solid #dde; 798 border-right: none; 799 font-size: 1.1em; 800 font-weight: bold; 801 text-transform: capitalize; 802 padding: .33em .75em .33em 1em; 803 border-radius: 1em 0 0 1em; 804 color: #444; 838 color: #2373A8; 839 line-height: 4.2rem; 840 } 841 #help-button span { 842 padding: .6rem 0 .1rem 0; 843 border-bottom: 1px solid #2373A8; 805 844 } 806 845 .help-box { … … 812 851 } 813 852 #content.with-help #help-button { 814 right: 282px; 853 right: 28.2rem; 854 background-color: #f5f5f5; 855 position: fixed; 856 border-top: 2px solid #FFD478; 857 border-left: 2px solid #FFD478; 858 border-bottom: 2px solid #FFD478; 859 border-bottom-left-radius: 1rem; 860 border-top-left-radius: 1rem; 815 861 } 816 862 #content.with-help #help { 817 863 display: block; 818 864 position: absolute; 819 top: 40px;865 top: 3.6rem; 820 866 right: 0; 821 width: 280px; 822 border-left: 2px solid #fc3; 867 width: 28rem; 868 border-left: 2px solid #FFD478; 869 border-top: 2px solid #FFD478; 823 870 margin-top: 0; 824 871 padding: 10px 0 0 0; … … 838 885 /* ------------------------------------------------------------------ popups */ 839 886 body.popup #wrapper, body.popup #top { 840 margin-top: -1.5em; 887 width: 100%; 888 padding: 0; 889 } 890 body.popup #wrapper { 841 891 float: none; 842 } 843 body.popup #top h1 { 844 background: transparent; 892 margin:0; 893 display: block; 894 } 895 body.popup h1, body.popup #top { 896 margin: 0; 897 border-bottom: 1px solid; 898 font-weight: normal; 899 color: #fff; 900 background: #575859; 901 font-size: 1.5em; 902 text-indent: .6rem; 903 line-height: 1.3em; 845 904 } 846 905 body.popup #main { 847 margin-left: -35px; 848 margin-bottom: 1em; 906 margin-bottom: 1em 0; 849 907 } 850 908 body.popup #content { 851 margin -left: 35px;852 margin-left: 2em; /* 3.2 */853 } 854 body.popup # footer{855 display: none; /* 3.2 */909 margin: 0; 910 padding: .6rem 0 !important; 911 } 912 body.popup #content h2 { 913 margin: 0 0 1em; 856 914 } 857 915 body.popup #footer p { 858 margin-left: 35px;859 916 border: none; 860 917 } … … 868 925 } 869 926 p.error, p.message, p.static-msg { 870 padding-top: 1 em;871 padding-bottom: 1 em;927 padding-top: 1rem; 928 padding-bottom: 1rem; 872 929 } 873 930 div.error, p.error { … … 883 940 div.static-msg a, p.static-msg a { 884 941 color: #fff; 942 } 943 #content > .message, #content > .error { 944 margin-right: 14em 945 } 946 /* ------------------------------------------------------------------ navigation */ 947 .anchor-nav { 948 background: #575859; 949 color: #fff; 950 padding: .4rem 1.2rem; 951 float: right; 885 952 } 886 953 /* ------------------------------------------------------------------ debug */ … … 924 991 vertical-align: middle; 925 992 } 926 927 993 /* Si quelque chose a besoin d'être caché sauf pour les revues d'écran */ 928 994 .hidden { … … 959 1025 overflow: auto; 960 1026 } 961 962 1027 .grid { 963 1028 background: transparent repeat url('grid.png') 0 0; 964 1029 } 965 966 1030 .line p { 967 1031 margin: 0; … … 970 1034 color: #666; 971 1035 } 972 973 1036 ul.nice { 974 1037 margin: 1em 0; … … 1005 1068 -------------------------------------------------------- */ 1006 1069 table { 1007 font-size: 1 em;1070 font-size: 1.2rem; 1008 1071 border-collapse: collapse; 1009 1072 margin: 0 0 1em 0; 1010 1073 } 1011 1074 tr.line:hover { 1012 background: # ddd;1075 background: #f3f3f3; 1013 1076 } 1014 1077 caption { 1015 1078 color: #333; 1016 font-size: 1.2em;1017 1079 font-weight: bold; 1018 1080 text-align: left; 1019 1081 margin-bottom: .5em; 1020 1082 } 1083 1021 1084 th, td { 1022 1085 border-width: 0 0 1px 0; 1023 1086 border-style: solid; 1024 border-color: # ccc;1025 padding: 3px 5px;1087 border-color: #e3e3e3; 1088 padding: .4rem .5rem; 1026 1089 vertical-align: top; 1027 1090 } 1028 1091 th { 1029 1092 text-align: left; 1030 border-bottom-color: # 666;1093 border-bottom-color: #aaa; 1031 1094 } 1032 1095 .noborder td, td.noborder, .noborder th, th.noborder { 1033 1096 border-width: 0; 1034 1097 } 1035 1036 1098 table .maximal, table.maximal { 1037 1099 width: 100%; … … 1040 1102 width: 1px; 1041 1103 } 1042 1043 1104 table .nowrap { 1044 1105 white-space: nowrap; … … 1131 1192 font-weight: normal; 1132 1193 } 1133 1134 1194 input, textarea, select { 1135 1195 background: #f9f9f9; … … 1137 1197 border-width: 1px; 1138 1198 border-style: solid; 1139 border-color: # 000 #ccc #ccc #000;1199 border-color: #666 #ccc #ccc #999; 1140 1200 } 1141 1201 input.invalid, textarea.invalid, select.invalid { … … 1146 1206 } 1147 1207 input, textarea, select, option { 1148 font: 1 em"DejaVu Sans","Lucida Grande","Lucida Sans Unicode",Arial,sans-serif;1208 font: 100% "DejaVu Sans","Lucida Grande","Lucida Sans Unicode",Arial,sans-serif; 1149 1209 } 1150 1210 input[type=text], input[type=password], textarea { … … 1152 1212 margin-right: .3em; 1153 1213 } 1154 input[type=checkbox], input[type=radio] {1155 border: none;1156 }1157 1214 textarea { 1158 1215 padding: 2px 0; 1159 1216 } 1160 1161 input[type=checkbox], input[type=radio] { 1217 input[type=checkbox], input[type=radio], input[type=file] { 1218 border: none; 1162 1219 margin: 0; 1163 1220 padding: 0; 1164 1221 background: transparent; 1165 1222 } 1166 1167 1223 label { 1168 1224 display: block; … … 1210 1266 resize: vertical; 1211 1267 } 1212 1213 1268 label.required { 1214 1269 font-weight: bold; … … 1232 1287 display: inline; 1233 1288 position: absolute; 1234 left: 1 5em;1289 left: 14.5em; 1235 1290 top: 0; 1236 1291 } 1237 1238 1292 label .maximal, textarea.maximal, input.maximal { 1239 1293 width: 100%; … … 1250 1304 padding-left: 20px; 1251 1305 } 1252 1253 a#toggle-filters {1254 font-weight: bold;1255 background: url(../images/plus.png) no-repeat 0 0;1256 padding-left: 20px;1257 }1258 1259 a#toggle-filters.opened {1260 background: url(../images/minus.png) no-repeat 0 0;1261 }1262 1263 1306 .constrained { 1264 1307 margin: 0; … … 1269 1312 1270 1313 /* --------------------------------------------------------------- buttons */ 1271 h2 a.button {1272 color: #333;1273 font-weight: normal;1274 font-size: .75em;1275 vertical-align: middle;1276 }1277 1314 /* commun */ 1278 1315 input[type=submit], … … 1287 1324 text-align: center; 1288 1325 text-decoration: none; 1289 padding: .1em .5em 0 .5em;1326 padding: .1em .5em; 1290 1327 text-shadow: 0 1px 1px rgba(0,0,0,.3); 1291 1328 border-radius: .2em; … … 1369 1406 content: "\ab\a0"; 1370 1407 } 1371 a.button.add { 1372 border-radius: .5em; 1373 margin-bottom: .1em; 1374 background: #2C8FD1 url(../images/add.png) no-repeat 6px center; 1375 color: #fff; 1376 padding: .2em 16px .2em 30px; 1377 border: 1px solid #2373A8; 1378 } 1379 a.button.add:hover, a.button.add:focus { 1380 background-color: #2373A8; 1381 } 1408 .button.add { 1409 background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #9dce2c), color-stop(1, #8cb82b) ); 1410 background:-moz-linear-gradient( center top, #9dce2c 5%, #8cb82b 100% ); 1411 filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#9dce2c', endColorstr='#8cb82b'); 1412 background-color:#9dce2c; 1413 border:1px solid #83c41a; 1414 padding:.6rem 1.8rem; 1415 text-shadow:1px 1px 0 #689324; 1416 color: #000; 1417 text-shadow: 1px 1px 0 #BBDB58; 1418 font-weight: normal; 1419 font-size: 1.4rem; 1420 } 1421 .button.add:hover, .button.add:focus { 1422 background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #8cb82b), color-stop(1, #9dce2c) ); 1423 background:-moz-linear-gradient( center top, #8cb82b 5%, #9dce2c 100% ); 1424 filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#8cb82b', endColorstr='#9dce2c'); 1425 background-color:#8cb82b; 1426 border:1px solid #83c41a; 1427 } 1428 .button-add:focus { 1429 outline: dotted 1px; 1430 } 1431 .button.add:active { 1432 position:relative; 1433 top:1px; 1434 } 1435 1382 1436 /* jQuery Autocomplete plugin */ 1383 1437 .ac_results { … … 1413 1467 } 1414 1468 1415 form#filters {font-size: 100%; background: #f0f0f0; padding: 1em; border-radius: .5em; border: 1px solid #ddd;} 1416 form#filters .margintop {padding-top: 1.33em;} 1417 form#filters ul, form#filters p {list-style-type:none;margin: 0; padding: 0 0 .5em 0; margin-left: 1em;} 1418 form#filters .col30 {border-left: 1px solid #999;} 1419 form#filters .col30 h3 {margin-left: 1em;} 1420 1421 p.line, li.line { position: relative; padding: 3px 0 0 28px; margin: 0 0 1em 0;} 1422 li.line input[type=submit] {position: absolute; left:0;top:0; padding: 0 .1em; margin: 0;} 1423 li.line input[type=checkbox], li.line input[type=checkbox] {position: absolute; left: 0; top: .2em; padding: 0 .1em; margin: 0;} 1424 li.line select { margin-right: 2em;} 1425 li.line label { display: block; width: 8em; float: left;} 1426 li.line label img {margin-right: 8px;} 1427 li.line span.or { 1428 text-align: right; 1429 margin-left: 5em; 1430 font-weight: bold; 1431 } 1432 p.line label.or + select {margin-left: 2em;} 1433 li.line { padding: 0 0 0 20px; height: 1em;} 1434 li.line label {width: auto;} 1435 1436 #available_filters input[type=submit] {padding: 0 .1em; margin-left: .5em;} 1437 1438 div.pagination span, div.pagination a { 1439 margin-right: 1em; 1440 } 1469 /* --------------------------------------------------------------------------- 1470 Media queries vite fait en attendant la reprise complète du layout 1471 ---------------------------------------------------------------------------- */ 1472 @media screen and (max-width: 920px) { 1473 #top, #top h1 a {width: 42px !important;overflow:hidden;} 1474 } 1475 @media screen and (max-width: 800px) { 1476 #top, #info-boxes, #info-box1, #info-box2 { 1477 display:inline-block; 1478 vertical-align:middle; 1479 margin:0; 1480 padding:0; 1481 line-height: 3.2rem; 1482 } 1483 #info-box1 select {width: 14rem;} 1484 #main-menu, #main, #content, #content h2, #entry-wrapper, #entry-sidebar, #entry-content, .two-cols .col, .two-cols .col:first-child { 1485 display:block; 1486 width: 98%; 1487 margin:0 auto; 1488 padding:0; 1489 float:none; 1490 text-align: left; 1491 clear: both; 1492 } 1493 #content { 1494 width: 100%; 1495 padding-top: .5em; 1496 } 1497 } 1498 @media screen and (max-width: 720px) { 1499 .smallscreen {display: none;} 1500 #help-button {width:20px; overflow: hidden;} 1501 } 1502 @media screen and (max-width: 492px) { 1503 #header {min-height:3.6rem;} 1504 #wrapper {font-size: 1.6rem;} 1505 .page-title, #info-boxes, .media-item {display: inline-block;} 1506 div.media-list .media-item {width: 90%; float: none} 1507 #top h1 a, #top {height: auto;} 1508 #info-box1 p.nomobile, label.nomobile {display: none;} 1509 #help-button {height:26px; width:26px; background-color: #A2CBE9; padding: 0; margin:0;font-size: 1rem;line-height: 68px} 1510 } -
inc/admin/class.dc.menu.php
r1179 r1315 4 4 # This file is part of Dotclear 2. 5 5 # 6 # Copyright (c) 2003-201 3Olivier Meunier & Association Dotclear6 # Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 14 14 class dcMenu 15 15 { 16 private $items; 16 17 private $id; 17 18 public $title; 19 public $separator; 18 20 19 public function __construct($id,$title,$ itemSpace='')21 public function __construct($id,$title,$separator='') 20 22 { 21 23 $this->id = $id; 22 24 $this->title = $title; 23 $this-> itemSpace = $itemSpace;25 $this->separator = $separator; 24 26 $this->items = array(); 27 } 28 29 public function getID() 30 { 31 return $this->id; 32 } 33 34 public function getTitle() 35 { 36 return $this->title; 37 } 38 39 public function getSeparator() 40 { 41 return $this->separator; 42 } 43 44 public function getItems() 45 { 46 return $this->items; 25 47 } 26 48 … … 39 61 } 40 62 63 protected function itemDef($title,$url,$img,$active,$id=null,$class=null) 64 { 65 if (is_array($url)) { 66 $link = $url[0]; 67 $ahtml = (!empty($url[1])) ? ' '.$url[1] : ''; 68 } else { 69 $link = $url; 70 $ahtml = ''; 71 } 72 73 return array( 74 'title' => $title, 75 'link' => $link, 76 'ahtml' => $ahtml, 77 'img' => dc_admin_icon_url($img), 78 'active' => (boolean) $active, 79 'id' => $id, 80 'class' => $class 81 ); 82 } 83 84 /** 85 @deprecated Use Template engine instead 86 */ 41 87 public function draw() 42 88 { … … 52 98 for ($i=0; $i<count($this->items); $i++) 53 99 { 54 if ($i+1 < count($this->items) && $this-> itemSpace!= '') {55 $res .= preg_replace('|</li>$|',$this-> itemSpace.'</li>',$this->items[$i]);100 if ($i+1 < count($this->items) && $this->separator != '') { 101 $res .= preg_replace('|</li>$|',$this->separator.'</li>',$this->drawItem($this->items[$i])); 56 102 $res .= "\n"; 57 103 } else { 58 $res .= $this-> items[$i]."\n";104 $res .= $this->drawItem($this->items[$i])."\n"; 59 105 } 60 106 } … … 65 111 } 66 112 67 protected function itemDef($title,$url,$img,$active,$id=null,$class=null) 113 /** 114 @deprecated Use Template engine instead 115 */ 116 protected function drawItem($item) 68 117 { 69 if (is_array($url)) {70 $link = $url[0];71 $ahtml = (!empty($url[1])) ? ' '.$url[1] : '';72 } else {73 $link = $url;74 $ahtml = '';75 }76 77 $img = dc_admin_icon_url($img);78 79 118 return 80 '<li'.(($ active || $class) ? ' class="'.(($active) ? 'active ' : '').(($class) ? $class: '').'"' : '').81 (($i d) ? ' id="'.$id.'"' : '').82 (($i mg) ? ' style="background-image: url('.$img.');"' : '').119 '<li'.(($item['active'] || $item['class']) ? ' class="'.(($item['active']) ? 'active ' : '').(($item['class']) ? $item['class'] : '').'"' : ''). 120 (($item['id']) ? ' id="'.$item['id'].'"' : ''). 121 (($item['img']) ? ' style="background-image: url('.$item['img'].');"' : ''). 83 122 '>'. 84 123 85 '<a href="'.$ link.'"'.$ahtml.'>'.$title.'</a></li>'."\n";124 '<a href="'.$item['link'].'"'.$item['ahtml'].'>'.$item['title'].'</a></li>'."\n"; 86 125 } 87 126 } -
inc/admin/lib.dc.page.php
r1312 r1315 4 4 # This file is part of Dotclear 2. 5 5 # 6 # Copyright (c) 2003-201 3Olivier Meunier & Association Dotclear6 # Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 22 22 { 23 23 global $core; 24 24 25 25 if ($core->blog && $core->auth->check($permissions,$core->blog->id)) 26 26 { 27 27 return; 28 28 } 29 29 30 30 if (session_id()) { 31 31 $core->session->destroy(); … … 33 33 http::redirect(DC_AUTH_PAGE); 34 34 } 35 35 36 36 # Check super admin 37 37 public static function checkSuper() 38 38 { 39 39 global $core; 40 40 41 41 if (!$core->auth->isSuperAdmin()) 42 42 { … … 47 47 } 48 48 } 49 49 50 50 # Top of admin page 51 public static function open($title='', $head='') 52 { 53 global $core; 54 55 # List of user's blogs 56 if ($core->auth->blog_count == 1 || $core->auth->blog_count > 20) 57 { 58 $blog_box = 59 '<p>'.__('Blog:').' <strong title="'.html::escapeHTML($core->blog->url).'">'. 60 html::escapeHTML($core->blog->name).'</strong>'; 61 62 if ($core->auth->blog_count > 20) { 63 $blog_box .= ' - <a href="blogs.php">'.__('Change blog').'</a>'; 64 } 65 $blog_box .= '</p>'; 66 } 67 else 68 { 69 $rs_blogs = $core->getBlogs(array('order'=>'LOWER(blog_name)','limit'=>20)); 70 $blogs = array(); 71 while ($rs_blogs->fetch()) { 72 $blogs[html::escapeHTML($rs_blogs->blog_name.' - '.$rs_blogs->blog_url)] = $rs_blogs->blog_id; 73 } 74 $blog_box = 75 '<p><label for="switchblog" class="classic nomobile">'. 76 __('Blogs:').'</label> '. 77 $core->formNonce(). 78 form::combo('switchblog',$blogs,$core->blog->id). 79 '</p>'. 80 '<noscript><p><input type="submit" value="'.__('ok').'" /></p></noscript>'; 81 } 82 83 $safe_mode = isset($_SESSION['sess_safe_mode']) && $_SESSION['sess_safe_mode']; 84 85 # Display 86 header('Content-Type: text/html; charset=UTF-8'); 87 echo 88 '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" '. 89 ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'."\n". 90 '<html xmlns="http://www.w3.org/1999/xhtml" '. 91 'xml:lang="'.$core->auth->getInfo('user_lang').'" '. 92 'lang="'.$core->auth->getInfo('user_lang').'">'."\n". 93 "<head>\n". 94 ' <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />'."\n". 95 ' <meta name="ROBOTS" content="NOARCHIVE,NOINDEX,NOFOLLOW" />'."\n". 96 ' <meta name="GOOGLEBOT" content="NOSNIPPET" />'."\n". 97 ' <meta name="viewport" content="width=device-width, initial-scale=1.0" />'."\n". 98 ' <title>'.$title.' - '.html::escapeHTML($core->blog->name).' - '.html::escapeHTML(DC_VENDOR_NAME).' - '.DC_VERSION.'</title>'."\n". 99 100 101 self::jsLoadIE7(). 102 ' <link rel="stylesheet" href="style/default.css" type="text/css" media="screen" />'."\n"; 103 if (l10n::getTextDirection($GLOBALS['_lang']) == 'rtl') { 104 echo 105 ' <link rel="stylesheet" href="style/default-rtl.css" type="text/css" media="screen" />'."\n"; 106 } 107 108 $core->auth->user_prefs->addWorkspace('interface'); 109 $user_ui_hide_std_favicon = $core->auth->user_prefs->interface->hide_std_favicon; 110 if (!$user_ui_hide_std_favicon) { 111 echo '<link rel="icon" type="image/png" href="images/favicon.png" />'; 112 } 113 114 echo 115 self::jsCommon(). 116 $head; 117 118 # --BEHAVIOR-- adminPageHTMLHead 119 $core->callBehavior('adminPageHTMLHead'); 120 121 echo 122 "</head>\n". 123 '<body id="dotclear-admin'. 124 ($safe_mode ? ' safe-mode' : ''). 125 '">'."\n". 126 127 '<div id="header">'. 128 '<ul id="prelude"><li><a href="#content">'.__('Go to the content').'</a></li><li><a href="#main-menu">'.__('Go to the menu').'</a></li></ul>'."\n". 129 '<div id="top"><h1><a href="index.php">'.DC_VENDOR_NAME.'</a></h1></div>'."\n"; 130 131 echo 132 '<div id="info-boxes">'. 133 '<div id="info-box1">'. 134 '<form action="index.php" method="post">'. 135 $blog_box. 136 '<p class="nomobile"><a href="'.$core->blog->url.'" onclick="window.open(this.href);return false;" title="'.__('Go to site').' ('.__('new window').')'.'">'.__('Go to site').' <img src="images/outgoing.png" alt="" /></a>'. 137 '</p></form>'. 138 '</div>'. 139 '<div id="info-box2">'. 140 '<a class="smallscreen"'.(preg_match('/index.php$/',$_SERVER['REQUEST_URI']) ? ' class="active"' : '').' href="index.php">'.__('My dashboard').'</a>'. 141 '<span class="smallscreen"> | </span><a class="smallscreen"'.(preg_match('/preferences.php(\?.*)?$/',$_SERVER['REQUEST_URI']) ? ' class="active smallscreen"' : '').' href="preferences.php">'.__('My preferences').'</a>'. 142 '<span class="smallscreen"> | </span><a href="index.php?logout=1" class="logout">'.sprintf(__('Logout %s'),$core->auth->userID()).' <img src="images/logout.png" alt="" /></a>'. 143 '</div>'. 144 '</div>'. 145 '</div>'; 146 147 echo 148 '<div id="wrapper">'."\n". 149 '<div id="main">'."\n". 150 '<div id="content">'."\n"; 151 152 # Safe mode 153 if ($safe_mode) 154 { 155 echo 156 '<div class="error"><h3>'.__('Safe mode').'</h3>'. 157 '<p>'.__('You are in safe mode. All plugins have been temporarily disabled. Remind to log out then log in again normally to get back all functionalities').'</p>'. 158 '</div>'; 159 } 160 51 public static function open($title='',$head='',$popup=false) 52 { 53 global $core, $_ctx; 54 55 $_ctx->popup = (boolean) $popup; 56 $_ctx->page_header = $head; 57 $_ctx->fillPageTitle($title); 58 59 ob_start(); 60 } 61 62 public static function close() 63 { 64 $res = ob_get_contents(); 65 ob_end_clean(); 66 67 global $core, $_ctx; 68 161 69 if ($core->error->flag()) { 162 echo 163 '<div class="error"><p><strong>'.(count($core->error->getErrors()) > 1 ? __('Errors:') : __('Error:')).'</p></strong>'. 164 $core->error->toHTML(). 165 '</div>'; 166 } 167 } 168 169 public static function close() 170 { 171 global $core; 172 173 $menu =& $GLOBALS['_menu']; 174 175 echo 176 "</div>\n". // End of #content 177 "</div>\n". // End of #main 178 179 '<div id="main-menu">'."\n". 180 181 '<form id="search-menu" action="search.php" method="get">'. 182 '<p><label for="q" class="hidden">'.__('Search:').' </label>'.form::field('q',30,255,''). 183 '<input type="submit" value="'.__('OK').'" /></p>'. 184 '</form>'; 185 186 foreach ($menu as $k => $v) { 187 echo $menu[$k]->draw(); 188 } 189 190 $text = sprintf(__('Thank you for using %s.'),'Dotclear '.DC_VERSION); 191 192 # --BEHAVIOR-- adminPageFooter 193 $textAlt = $core->callBehavior('adminPageFooter',$core,$text); 194 if ($textAlt != '') { 195 $text = $textAlt; 196 } 197 $text = html::escapeHTML($text); 198 199 echo 200 '</div>'."\n". // End of #main-menu 201 '<div id="footer"><a href="http://dotclear.org/" title="'.$text.'"><img src="style/dc_logo_footer.png" alt="'.$text.'" /></a></div>'."\n". 202 "</div>\n"; // End of #wrapper 203 204 if (defined('DC_DEV') && DC_DEV === true) { 205 echo self::debugInfo(); 206 } 207 208 echo 209 '</body></html>'; 210 } 211 212 public static function openPopup($title='', $head='') 213 { 214 global $core; 215 216 # Display 217 header('Content-Type: text/html; charset=UTF-8'); 218 echo 219 '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" '. 220 ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'."\n". 221 '<html xmlns="http://www.w3.org/1999/xhtml" '. 222 'xml:lang="'.$core->auth->getInfo('user_lang').'" '. 223 'lang="'.$core->auth->getInfo('user_lang').'">'."\n". 224 '<meta name="viewport" content="width=device-width, initial-scale=1.0" />'."\n". 225 "<head>\n". 226 ' <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />'."\n". 227 ' <title>'.$title.' - '.html::escapeHTML($core->blog->name).' - '.html::escapeHTML(DC_VENDOR_NAME).' - '.DC_VERSION.'</title>'."\n". 228 229 ' <meta name="ROBOTS" content="NOARCHIVE,NOINDEX,NOFOLLOW" />'."\n". 230 ' <meta name="GOOGLEBOT" content="NOSNIPPET" />'."\n". 231 232 self::jsLoadIE7(). 233 ' <link rel="stylesheet" href="style/default.css" type="text/css" media="screen" />'."\n"; 234 if (l10n::getTextDirection($GLOBALS['_lang']) == 'rtl') { 235 echo 236 ' <link rel="stylesheet" href="style/default-rtl.css" type="text/css" media="screen" />'."\n"; 237 } 238 239 echo 240 self::jsCommon(). 241 $head; 242 243 # --BEHAVIOR-- adminPageHTMLHead 244 $core->callBehavior('adminPageHTMLHead'); 245 246 echo 247 "</head>\n". 248 '<body id="dotclear-admin" class="popup">'."\n". 249 250 '<div id="top hidden"><h1>'.DC_VENDOR_NAME.'</h1></div>'."\n"; 251 252 echo 253 '<div id="wrapper">'."\n". 254 '<div id="main">'."\n". 255 '<div id="content">'."\n"; 256 257 if ($core->error->flag()) { 258 echo 259 '<div class="error"><strong>'.__('Errors:').'</strong>'. 260 $core->error->toHTML(). 261 '</div>'; 262 } 263 } 264 70 foreach($core->error->getErrors() as $e) { 71 $_ctx->addError($e); 72 } 73 } 74 $_ctx->page_content = $res; 75 $core->tpl->display('page_layout.html.twig'); 76 } 77 78 public static function openPopup($title='',$head='') 79 { 80 self::open($title,$head,true); 81 } 82 265 83 public static function closePopup() 266 84 { 267 echo 268 "</div>\n". // End of #content 269 "</div>\n". // End of #main 270 '<div id="footer"><p> </p></div>'."\n". 271 "</div>\n". // End of #wrapper 272 '</body></html>'; 85 self::close(); 273 86 } 274 87 … … 276 89 { 277 90 global $core; 278 91 279 92 $res = ''; 280 93 if ($msg != '') { 281 94 $res = ($div ? '<div class="message">' : '').'<p'.($div ? '' : ' class="message"').'>'. 282 ($timestamp ? dt::str(__('%H:%M:%S:'),null,$core->auth->getInfo('user_tz')).' ' : '').$msg.283 '</p>'.($div ? '</div>' : '');95 ($timestamp ? dt::str(__('%H:%M:%S:'),null,$core->auth->getInfo('user_tz')).' ' : '').$msg. 96 '</p>'.($div ? '</div>' : ''); 284 97 if ($echo) { 285 98 echo $res; … … 288 101 return $res; 289 102 } 290 291 private static function debugInfo() 292 { 293 $global_vars = implode(', ',array_keys($GLOBALS)); 294 295 $res = 296 '<div id="debug"><div>'. 297 '<p>memory usage: '.memory_get_usage().' ('.files::size(memory_get_usage()).')</p>'; 298 299 if (function_exists('xdebug_get_profiler_filename')) 300 { 301 $res .= '<p>Elapsed time: '.xdebug_time_index().' seconds</p>'; 302 303 $prof_file = xdebug_get_profiler_filename(); 304 if ($prof_file) { 305 $res .= '<p>Profiler file : '.xdebug_get_profiler_filename().'</p>'; 306 } else { 307 $prof_url = http::getSelfURI(); 308 $prof_url .= (strpos($prof_url,'?') === false) ? '?' : '&'; 309 $prof_url .= 'XDEBUG_PROFILE'; 310 $res .= '<p><a href="'.html::escapeURL($prof_url).'">Trigger profiler</a></p>'; 311 } 312 313 /* xdebug configuration: 314 zend_extension = /.../xdebug.so 315 xdebug.auto_trace = On 316 xdebug.trace_format = 0 317 xdebug.trace_options = 1 318 xdebug.show_mem_delta = On 319 xdebug.profiler_enable = 0 320 xdebug.profiler_enable_trigger = 1 321 xdebug.profiler_output_dir = /tmp 322 xdebug.profiler_append = 0 323 xdebug.profiler_output_name = timestamp 324 */ 325 } 326 327 $res .= 328 '<p>Global vars: '.$global_vars.'</p>'. 329 '</div></div>'; 330 331 return $res; 332 } 333 103 334 104 public static function help($page,$index='') 335 105 { 336 106 # Deprecated but we keep this for plugins. 337 107 } 338 108 339 109 public static function helpBlock() 340 110 { … … 343 113 return; 344 114 }; 345 115 346 116 global $__resources; 347 117 if (empty($__resources['help'])) { 348 118 return; 349 119 } 350 120 351 121 $content = ''; 352 122 foreach ($args as $v) … … 356 126 continue; 357 127 } 358 128 359 129 if (!isset($__resources['help'][$v])) { 360 130 continue; … … 364 134 continue; 365 135 } 366 136 367 137 $fc = file_get_contents($f); 368 138 if (preg_match('|<body[^>]*?>(.*?)</body>|ms',$fc,$matches)) { … … 372 142 } 373 143 } 374 144 375 145 if (trim($content) == '') { 376 146 return; 377 147 } 378 148 379 149 echo 380 150 '<div id="help"><hr /><div class="help-content clear"><h2>'.__('Help').'</h2>'. … … 382 152 '</div></div>'; 383 153 } 384 154 385 155 public static function jsLoad($src) 386 156 { … … 391 161 } 392 162 } 393 163 394 164 public static function jsVar($n,$v) 395 165 { 396 166 return $n." = '".html::escapeJS($v)."';\n"; 397 167 } 398 168 399 169 public static function jsCommon() 400 170 { … … 405 175 self::jsLoad('js/common.js'). 406 176 self::jsLoad('js/prelude.js'). 407 177 408 178 '<script type="text/javascript">'."\n". 409 179 "//<![CDATA[\n". 410 180 self::jsVar('dotclear.nonce',$GLOBALS['core']->getNonce()). 411 181 412 182 self::jsVar('dotclear.img_plus_src','images/expand.png'). 413 183 self::jsVar('dotclear.img_plus_alt',__('uncover')). … … 416 186 self::jsVar('dotclear.img_menu_on','images/menu_on.png'). 417 187 self::jsVar('dotclear.img_menu_off','images/menu_off.png'). 418 188 419 189 self::jsVar('dotclear.msg.help', 420 __('Help about this page')). 421 self::jsVar('dotclear.msg.help_hide', 422 __('Hide')). 190 __('help')). 423 191 self::jsVar('dotclear.msg.no_selection', 424 192 __('no selection')). … … 490 258 "</script>\n"; 491 259 } 492 260 493 261 public static function jsLoadIE7() 494 262 { … … 499 267 '<![endif]-->'."\n"; 500 268 } 501 269 502 270 public static function jsConfirmClose() 503 271 { … … 511 279 $args = ''; 512 280 } 513 281 514 282 return 515 283 self::jsLoad('js/confirm-close.js'). … … 521 289 "</script>\n"; 522 290 } 523 291 524 292 public static function jsPageTabs($default=null) 525 293 { … … 527 295 $default = "'".html::escapeJS($default)."'"; 528 296 } 297 298 return 299 self::jsLoad('js/jquery/jquery.pageTabs.js'). 300 '<script type="text/javascript">'."\n". 301 "//<![CDATA[\n". 302 "\$(function() {\n". 303 " \$.pageTabs(".$default.");\n". 304 "});\n". 305 "\n//]]>\n". 306 "</script>\n"; 307 } 308 309 public static function jsModal() 310 { 311 return 312 '<link rel="stylesheet" type="text/css" href="style/modal/modal.css" />'."\n". 313 self::jsLoad('js/jquery/jquery.modal.js'). 314 '<script type="text/javascript">'."\n". 315 "//<![CDATA[\n". 316 self::jsVar('$.modal.prototype.params.loader_img','style/modal/loader.gif'). 317 self::jsVar('$.modal.prototype.params.close_img','style/modal/close.png'). 318 "\n//]]>\n". 319 "</script>\n"; 320 } 321 322 public static function jsColorPicker() 323 { 324 return 325 '<link rel="stylesheet" type="text/css" href="style/farbtastic/farbtastic.css" />'."\n". 326 self::jsLoad('js/jquery/jquery.farbtastic.js'). 327 self::jsLoad('js/color-picker.js'); 328 } 329 330 public static function jsDatePicker() 331 { 332 return 333 '<link rel="stylesheet" type="text/css" href="style/date-picker.css" />'."\n". 334 self::jsLoad('js/date-picker.js'). 335 '<script type="text/javascript">'."\n". 336 "//<![CDATA[\n". 337 338 "datePicker.prototype.months[0] = '".html::escapeJS(__('January'))."'; ". 339 "datePicker.prototype.months[1] = '".html::escapeJS(__('February'))."'; ". 340 "datePicker.prototype.months[2] = '".html::escapeJS(__('March'))."'; ". 341 "datePicker.prototype.months[3] = '".html::escapeJS(__('April'))."'; ". 342 "datePicker.prototype.months[4] = '".html::escapeJS(__('May'))."'; ". 343 "datePicker.prototype.months[5] = '".html::escapeJS(__('June'))."'; ". 344 "datePicker.prototype.months[6] = '".html::escapeJS(__('July'))."'; ". 345 "datePicker.prototype.months[7] = '".html::escapeJS(__('August'))."'; ". 346 "datePicker.prototype.months[8] = '".html::escapeJS(__('September'))."'; ". 347 "datePicker.prototype.months[9] = '".html::escapeJS(__('October'))."'; ". 348 "datePicker.prototype.months[10] = '".html::escapeJS(__('November'))."'; ". 349 "datePicker.prototype.months[11] = '".html::escapeJS(__('December'))."'; ". 350 351 "datePicker.prototype.days[0] = '".html::escapeJS(__('Monday'))."'; ". 352 "datePicker.prototype.days[1] = '".html::escapeJS(__('Tuesday'))."'; ". 353 "datePicker.prototype.days[2] = '".html::escapeJS(__('Wednesday'))."'; ". 354 "datePicker.prototype.days[3] = '".html::escapeJS(__('Thursday'))."'; ". 355 "datePicker.prototype.days[4] = '".html::escapeJS(__('Friday'))."'; ". 356 "datePicker.prototype.days[5] = '".html::escapeJS(__('Saturday'))."'; ". 357 "datePicker.prototype.days[6] = '".html::escapeJS(__('Sunday'))."'; ". 358 359 "datePicker.prototype.img_src = 'images/date-picker.png'; ". 360 361 "datePicker.prototype.close_msg = '".html::escapeJS(__('close'))."'; ". 362 "datePicker.prototype.now_msg = '".html::escapeJS(__('now'))."'; ". 363 364 "\n//]]>\n". 365 "</script>\n"; 366 } 367 368 public static function jsToolBar() 369 { 370 $res = 371 '<link rel="stylesheet" type="text/css" href="style/jsToolBar/jsToolBar.css" />'. 372 '<script type="text/javascript" src="js/jsToolBar/jsToolBar.js"></script>'; 373 374 if (isset($GLOBALS['core']->auth) && $GLOBALS['core']->auth->getOption('enable_wysiwyg')) { 375 $res .= '<script type="text/javascript" src="js/jsToolBar/jsToolBar.wysiwyg.js"></script>'; 376 } 377 378 $res .= 379 '<script type="text/javascript" src="js/jsToolBar/jsToolBar.dotclear.js"></script>'. 380 '<script type="text/javascript">'."\n". 381 "//<![CDATA[\n". 382 "jsToolBar.prototype.dialog_url = 'popup.php'; ". 383 "jsToolBar.prototype.iframe_css = '". 384 'body{'. 385 'font: 12px "DejaVu Sans","Lucida Grande","Lucida Sans Unicode",Arial,sans-serif;'. 386 'color : #000;'. 387 'background: #f9f9f9;'. 388 'margin: 0;'. 389 'padding : 2px;'. 390 'border: none;'. 391 (l10n::getTextDirection($GLOBALS['_lang']) == 'rtl' ? 'direction:rtl;' : ''). 392 '}'. 393 'pre, code, kbd, samp {'. 394 'font-family:"Courier New",Courier,monospace;'. 395 'font-size : 1.1em;'. 396 '}'. 397 'code {'. 398 'color : #666;'. 399 'font-weight : bold;'. 400 '}'. 401 'body > p:first-child {'. 402 'margin-top: 0;'. 403 '}'. 404 "'; ". 405 "jsToolBar.prototype.base_url = '".html::escapeJS($GLOBALS['core']->blog->host)."'; ". 406 "jsToolBar.prototype.switcher_visual_title = '".html::escapeJS(__('visual'))."'; ". 407 "jsToolBar.prototype.switcher_source_title = '".html::escapeJS(__('source'))."'; ". 408 "jsToolBar.prototype.legend_msg = '". 409 html::escapeJS(__('You can use the following shortcuts to format your text.'))."'; ". 410 "jsToolBar.prototype.elements.blocks.options.none = '".html::escapeJS(__('-- none --'))."'; ". 411 "jsToolBar.prototype.elements.blocks.options.nonebis = '".html::escapeJS(__('-- block format --'))."'; ". 412 "jsToolBar.prototype.elements.blocks.options.p = '".html::escapeJS(__('Paragraph'))."'; ". 413 "jsToolBar.prototype.elements.blocks.options.h1 = '".html::escapeJS(__('Level 1 header'))."'; ". 414 "jsToolBar.prototype.elements.blocks.options.h2 = '".html::escapeJS(__('Level 2 header'))."'; ". 415 "jsToolBar.prototype.elements.blocks.options.h3 = '".html::escapeJS(__('Level 3 header'))."'; ". 416 "jsToolBar.prototype.elements.blocks.options.h4 = '".html::escapeJS(__('Level 4 header'))."'; ". 417 "jsToolBar.prototype.elements.blocks.options.h5 = '".html::escapeJS(__('Level 5 header'))."'; ". 418 "jsToolBar.prototype.elements.blocks.options.h6 = '".html::escapeJS(__('Level 6 header'))."'; ". 419 "jsToolBar.prototype.elements.strong.title = '".html::escapeJS(__('Strong emphasis'))."'; ". 420 "jsToolBar.prototype.elements.em.title = '".html::escapeJS(__('Emphasis'))."'; ". 421 "jsToolBar.prototype.elements.ins.title = '".html::escapeJS(__('Inserted'))."'; ". 422 "jsToolBar.prototype.elements.del.title = '".html::escapeJS(__('Deleted'))."'; ". 423 "jsToolBar.prototype.elements.quote.title = '".html::escapeJS(__('Inline quote'))."'; ". 424 "jsToolBar.prototype.elements.code.title = '".html::escapeJS(__('Code'))."'; ". 425 "jsToolBar.prototype.elements.br.title = '".html::escapeJS(__('Line break'))."'; ". 426 "jsToolBar.prototype.elements.blockquote.title = '".html::escapeJS(__('Blockquote'))."'; ". 427 "jsToolBar.prototype.elements.pre.title = '".html::escapeJS(__('Preformated text'))."'; ". 428 "jsToolBar.prototype.elements.ul.title = '".html::escapeJS(__('Unordered list'))."'; ". 429 "jsToolBar.prototype.elements.ol.title = '".html::escapeJS(__('Ordered list'))."'; ". 430 431 "jsToolBar.prototype.elements.link.title = '".html::escapeJS(__('Link'))."'; ". 432 "jsToolBar.prototype.elements.link.href_prompt = '".html::escapeJS(__('URL?'))."'; ". 433 "jsToolBar.prototype.elements.link.hreflang_prompt = '".html::escapeJS(__('Language?'))."'; ". 434 435 "jsToolBar.prototype.elements.img.title = '".html::escapeJS(__('External image'))."'; ". 436 "jsToolBar.prototype.elements.img.src_prompt = '".html::escapeJS(__('URL?'))."'; ". 437 438 "jsToolBar.prototype.elements.img_select.title = '".html::escapeJS(__('Media chooser'))."'; ". 439 "jsToolBar.prototype.elements.post_link.title = '".html::escapeJS(__('Link to an entry'))."'; "; 440 441 if (!$GLOBALS['core']->auth->check('media,media_admin',$GLOBALS['core']->blog->id)) { 442 $res .= "jsToolBar.prototype.elements.img_select.disabled = true;\n"; 443 } 444 445 $res .= 446 "\n//]]>\n". 447 "</script>\n"; 448 449 return $res; 450 } 451 452 public static function jsUpload($params=array(),$base_url=null) 453 { 454 if (!$base_url) { 455 $base_url = path::clean(dirname(preg_replace('/(\?.*$)?/','',$_SERVER['REQUEST_URI']))).'/'; 456 } 457 458 $params = array_merge($params,array( 459 'sess_id='.session_id(), 460 'sess_uid='.$_SESSION['sess_browser_uid'], 461 'xd_check='.$GLOBALS['core']->getNonce() 462 )); 463 464 return 465 '<link rel="stylesheet" type="text/css" href="style/jsUpload/style.css" />'."\n". 529 466 530 return 531 self::jsLoad('js/jquery/jquery.pageTabs.js'). 532 '<script type="text/javascript">'."\n". 533 "//<![CDATA[\n". 534 "\$(function() {\n". 535 " \$.pageTabs(".$default.");\n". 536 "});\n". 537 "\n//]]>\n". 538 "</script>\n"; 539 } 467 '<script id="template-upload" type="text/x-tmpl"> 468 {% for (var i=0, file; file=o.files[i]; i++) { %} 469 <tr class="template-upload fade"> 470 <td> 471 <span class="preview"></span> 472 </td> 473 <td> 474 <p class="name">{%=file.name%}</p> 475 {% if (file.error) { %} 476 <div><span class="label label-error">'.__('Error:').'</span> {%=file.error%}</div> 477 {% } %} 478 </td> 479 <td> 480 <p class="size">{%=o.formatFileSize(file.size)%}</p> 481 {% if (!o.files.error) { %} 482 <div class="progress progress-success progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="bar" style="width:0%;"></div></div> 483 {% } %} 484 </td> 485 <td> 486 {% if (!o.files.error && !i && !o.options.autoUpload) { %} 487 <input type="submit" class="button start" value="'.__('Send').'"/> 488 {% } %} 489 </td> 490 </tr> 491 {% } %} 492 </script> 493 <!-- The template to display files available for download --> 494 <script id="template-download" type="text/x-tmpl"> 495 {% for (var i=0, file; file=o.files[i]; i++) { %} 496 <tr class="template-download fade"> 497 <td> 498 <span class="preview"> 499 {% if (file.thumbnail_url) { %} 500 <a href="{%=file.url%}" title="{%=file.name%}" data-gallery="gallery" download="{%=file.name%}"><img src="{%=file.thumbnail_url%}"></a> 501 {% } %} 502 </span> 503 </td> 504 <td> 505 <p class="name">{%=file.name%}</p> 506 {% if (file.error) { %} 507 <div><span class="label label-important">'.__('Error:').'</span> {%=file.error%}</div> 508 {% } %} 509 </td> 510 <td> 511 <span class="size">{%=o.formatFileSize(file.size)%}</span> 512 </td> 513 <td> 514 {% if (file.error) { %} 515 <span class="upload-status error"></span> 516 {% } else { %} 517 <span class="upload-status ok"></span> 518 {% } %} 519 </td> 520 </tr> 521 {% } %} 522 </script>'. 540 523 541 public static function jsModal() 542 { 543 return 544 '<link rel="stylesheet" type="text/css" href="style/modal/modal.css" />'."\n". 545 self::jsLoad('js/jquery/jquery.modal.js'). 546 '<script type="text/javascript">'."\n". 547 "//<![CDATA[\n". 548 self::jsVar('$.modal.prototype.params.loader_img','style/modal/loader.gif'). 549 self::jsVar('$.modal.prototype.params.close_img','style/modal/close.png'). 550 "\n//]]>\n". 551 "</script>\n"; 552 } 553 554 public static function jsColorPicker() 555 { 556 return 557 '<link rel="stylesheet" type="text/css" href="style/farbtastic/farbtastic.css" />'."\n". 558 self::jsLoad('js/jquery/jquery.farbtastic.js'). 559 self::jsLoad('js/color-picker.js'); 560 } 561 562 public static function jsDatePicker() 563 { 564 return 565 '<link rel="stylesheet" type="text/css" href="style/date-picker.css" />'."\n". 566 self::jsLoad('js/date-picker.js'). 567 '<script type="text/javascript">'."\n". 568 "//<![CDATA[\n". 569 570 "datePicker.prototype.months[0] = '".html::escapeJS(__('January'))."'; ". 571 "datePicker.prototype.months[1] = '".html::escapeJS(__('February'))."'; ". 572 "datePicker.prototype.months[2] = '".html::escapeJS(__('March'))."'; ". 573 "datePicker.prototype.months[3] = '".html::escapeJS(__('April'))."'; ". 574 "datePicker.prototype.months[4] = '".html::escapeJS(__('May'))."'; ". 575 "datePicker.prototype.months[5] = '".html::escapeJS(__('June'))."'; ". 576 "datePicker.prototype.months[6] = '".html::escapeJS(__('July'))."'; ". 577 "datePicker.prototype.months[7] = '".html::escapeJS(__('August'))."'; ". 578 "datePicker.prototype.months[8] = '".html::escapeJS(__('September'))."'; ". 579 "datePicker.prototype.months[9] = '".html::escapeJS(__('October'))."'; ". 580 "datePicker.prototype.months[10] = '".html::escapeJS(__('November'))."'; ". 581 "datePicker.prototype.months[11] = '".html::escapeJS(__('December'))."'; ". 582 583 "datePicker.prototype.days[0] = '".html::escapeJS(__('Monday'))."'; ". 584 "datePicker.prototype.days[1] = '".html::escapeJS(__('Tuesday'))."'; ". 585 "datePicker.prototype.days[2] = '".html::escapeJS(__('Wednesday'))."'; ". 586 "datePicker.prototype.days[3] = '".html::escapeJS(__('Thursday'))."'; ". 587 "datePicker.prototype.days[4] = '".html::escapeJS(__('Friday'))."'; ". 588 "datePicker.prototype.days[5] = '".html::escapeJS(__('Saturday'))."'; ". 589 "datePicker.prototype.days[6] = '".html::escapeJS(__('Sunday'))."'; ". 590 591 "datePicker.prototype.img_src = 'images/date-picker.png'; ". 592 593 "datePicker.prototype.close_msg = '".html::escapeJS(__('close'))."'; ". 594 "datePicker.prototype.now_msg = '".html::escapeJS(__('now'))."'; ". 595 596 "\n//]]>\n". 597 "</script>\n"; 598 } 599 600 public static function jsToolBar() 601 { 602 $res = 603 '<link rel="stylesheet" type="text/css" href="style/jsToolBar/jsToolBar.css" />'. 604 '<script type="text/javascript" src="js/jsToolBar/jsToolBar.js"></script>'; 605 606 if (isset($GLOBALS['core']->auth) && $GLOBALS['core']->auth->getOption('enable_wysiwyg')) { 607 $res .= '<script type="text/javascript" src="js/jsToolBar/jsToolBar.wysiwyg.js"></script>'; 608 } 609 610 $res .= 611 '<script type="text/javascript" src="js/jsToolBar/jsToolBar.dotclear.js"></script>'. 612 '<script type="text/javascript">'."\n". 613 "//<![CDATA[\n". 614 "jsToolBar.prototype.dialog_url = 'popup.php'; ". 615 "jsToolBar.prototype.iframe_css = '". 616 'body{'. 617 'font: 12px "DejaVu Sans","Lucida Grande","Lucida Sans Unicode",Arial,sans-serif;'. 618 'color : #000;'. 619 'background: #f9f9f9;'. 620 'margin: 0;'. 621 'padding : 2px;'. 622 'border: none;'. 623 (l10n::getTextDirection($GLOBALS['_lang']) == 'rtl' ? 'direction:rtl;' : ''). 624 '}'. 625 'pre, code, kbd, samp {'. 626 'font-family:"Courier New",Courier,monospace;'. 627 'font-size : 1.1em;'. 628 '}'. 629 'code {'. 630 'color : #666;'. 631 'font-weight : bold;'. 632 '}'. 633 'body > p:first-child {'. 634 'margin-top: 0;'. 635 '}'. 636 "'; ". 637 "jsToolBar.prototype.base_url = '".html::escapeJS($GLOBALS['core']->blog->host)."'; ". 638 "jsToolBar.prototype.switcher_visual_title = '".html::escapeJS(__('visual'))."'; ". 639 "jsToolBar.prototype.switcher_source_title = '".html::escapeJS(__('source'))."'; ". 640 "jsToolBar.prototype.legend_msg = '". 641 html::escapeJS(__('You can use the following shortcuts to format your text.'))."'; ". 642 "jsToolBar.prototype.elements.blocks.options.none = '".html::escapeJS(__('-- none --'))."'; ". 643 "jsToolBar.prototype.elements.blocks.options.nonebis = '".html::escapeJS(__('-- block format --'))."'; ". 644 "jsToolBar.prototype.elements.blocks.options.p = '".html::escapeJS(__('Paragraph'))."'; ". 645 "jsToolBar.prototype.elements.blocks.options.h1 = '".html::escapeJS(__('Level 1 header'))."'; ". 646 "jsToolBar.prototype.elements.blocks.options.h2 = '".html::escapeJS(__('Level 2 header'))."'; ". 647 "jsToolBar.prototype.elements.blocks.options.h3 = '".html::escapeJS(__('Level 3 header'))."'; ". 648 "jsToolBar.prototype.elements.blocks.options.h4 = '".html::escapeJS(__('Level 4 header'))."'; ". 649 "jsToolBar.prototype.elements.blocks.options.h5 = '".html::escapeJS(__('Level 5 header'))."'; ". 650 "jsToolBar.prototype.elements.blocks.options.h6 = '".html::escapeJS(__('Level 6 header'))."'; ". 651 "jsToolBar.prototype.elements.strong.title = '".html::escapeJS(__('Strong emphasis'))."'; ". 652 "jsToolBar.prototype.elements.em.title = '".html::escapeJS(__('Emphasis'))."'; ". 653 "jsToolBar.prototype.elements.ins.title = '".html::escapeJS(__('Inserted'))."'; ". 654 "jsToolBar.prototype.elements.del.title = '".html::escapeJS(__('Deleted'))."'; ". 655 "jsToolBar.prototype.elements.quote.title = '".html::escapeJS(__('Inline quote'))."'; ". 656 "jsToolBar.prototype.elements.code.title = '".html::escapeJS(__('Code'))."'; ". 657 "jsToolBar.prototype.elements.br.title = '".html::escapeJS(__('Line break'))."'; ". 658 "jsToolBar.prototype.elements.blockquote.title = '".html::escapeJS(__('Blockquote'))."'; ". 659 "jsToolBar.prototype.elements.pre.title = '".html::escapeJS(__('Preformated text'))."'; ". 660 "jsToolBar.prototype.elements.ul.title = '".html::escapeJS(__('Unordered list'))."'; ". 661 "jsToolBar.prototype.elements.ol.title = '".html::escapeJS(__('Ordered list'))."'; ". 662 663 "jsToolBar.prototype.elements.link.title = '".html::escapeJS(__('Link'))."'; ". 664 "jsToolBar.prototype.elements.link.href_prompt = '".html::escapeJS(__('URL?'))."'; ". 665 "jsToolBar.prototype.elements.link.hreflang_prompt = '".html::escapeJS(__('Language?'))."'; ". 666 667 "jsToolBar.prototype.elements.img.title = '".html::escapeJS(__('External image'))."'; ". 668 "jsToolBar.prototype.elements.img.src_prompt = '".html::escapeJS(__('URL?'))."'; ". 669 670 "jsToolBar.prototype.elements.img_select.title = '".html::escapeJS(__('Media chooser'))."'; ". 671 "jsToolBar.prototype.elements.post_link.title = '".html::escapeJS(__('Link to an entry'))."'; "; 672 673 if (!$GLOBALS['core']->auth->check('media,media_admin',$GLOBALS['core']->blog->id)) { 674 $res .= "jsToolBar.prototype.elements.img_select.disabled = true;\n"; 675 } 676 677 $res .= 678 "\n//]]>\n". 679 "</script>\n"; 680 681 return $res; 682 } 683 684 public static function jsUpload($params=array(),$base_url=null) 685 { 686 if (!$base_url) { 687 $base_url = path::clean(dirname(preg_replace('/(\?.*$)?/','',$_SERVER['REQUEST_URI']))).'/'; 688 } 689 690 $params = array_merge($params,array( 691 'sess_id='.session_id(), 692 'sess_uid='.$_SESSION['sess_browser_uid'], 693 'xd_check='.$GLOBALS['core']->getNonce() 694 )); 695 696 return 697 '<link rel="stylesheet" type="text/css" href="style/jsUpload/style.css" />'."\n". 698 699 '<script id="template-upload" type="text/x-tmpl"> 700 {% for (var i=0, file; file=o.files[i]; i++) { %} 701 <div class="template-upload fade"> 702 <div class="upload-file"> 703 <div class="upload-fileinfo"> 704 <span class="upload-filename">{%=file.name%}</span> 705 <span class="upload-filesize">({%=o.formatFileSize(file.size)%})</span> 706 <span class="upload-filecancel cancel">'.__('Cancel').'</span> 707 {% if (!o.files.error && !i && !o.options.autoUpload) { %} 708 <input type="submit" class="button start" value="'.__('Send').'"/> 709 {% } %} 710 <span class="upload-filemsg"></span> 711 </div> 712 {% if (!o.files.error) { %} 713 <div class="upload-progress progress progress-success progress-striped active"><div class="bar" style="width:0%;"></div></div> 714 {% } %} 715 </div> 716 {% } %} 717 </script> 718 <!-- The template to display files available for download --> 719 <script id="template-download" type="text/x-tmpl"> 720 {% for (var i=0, file; file=o.files[i]; i++) { %} 721 <div class="template-download fade"> 722 <div class="upload-file"> 723 <div class="upload-fileinfo"> 724 <span class="upload-filename">{%=file.name%}</span> 725 <span class="upload-filesize">({%=o.formatFileSize(file.size)%})</span> 726 <span class="upload-filemsg{% if (file.error) { %} upload-error{% } %}"> 727 {% if (file.error) { %} 728 '.__('Error:').' {%=file.error%} 729 {% } else { %} 730 '.__('File successfully uploaded.').' 731 {% } %} 732 </span> 733 </div> 734 <div class="upload-progress"> 735 {% if (!file.error) { %} 736 <div class="bar" style="width:100%;">100%</div> 737 {% } %} 738 </div> 739 </div> 740 {% } %} 741 </script>'. 742 743 self::jsLoad('js/jsUpload/vendor/jquery.ui.widget.js'). 744 self::jsLoad('js/jsUpload/tmpl.js'). 745 self::jsLoad('js/jsUpload/load-image.js'). 746 self::jsLoad('js/jsUpload/jquery.iframe-transport.js'). 747 self::jsLoad('js/jsUpload/jquery.fileupload.js'). 748 self::jsLoad('js/jsUpload/jquery.fileupload-process.js'). 749 self::jsLoad('js/jsUpload/jquery.fileupload-resize.js'). 750 self::jsLoad('js/jsUpload/jquery.fileupload-ui.js'). 751 752 '<script type="text/javascript">'."\n". 753 "//<![CDATA[\n". 754 "dotclear.jsUpload = {};\n". 755 "dotclear.jsUpload.msg = {};\n". 756 self::jsVar('dotclear.msg.enhanced_uploader_activate',__('Temporarily activate enhanced uploader')). 757 self::jsVar('dotclear.msg.enhanced_uploader_disable',__('Temporarily disable enhanced uploader')). 758 self::jsVar('dotclear.jsUpload.msg.limit_exceeded',__('Limit exceeded.')). 759 self::jsVar('dotclear.jsUpload.msg.size_limit_exceeded',__('File size exceeds allowed limit.')). 760 self::jsVar('dotclear.jsUpload.msg.canceled',__('Canceled.')). 761 self::jsVar('dotclear.jsUpload.msg.http_error',__('HTTP Error:')). 762 self::jsVar('dotclear.jsUpload.msg.error',__('Error:')). 763 self::jsVar('dotclear.jsUpload.msg.choose_file',__('Choose file')). 764 self::jsVar('dotclear.jsUpload.msg.choose_files',__('Choose files')). 765 self::jsVar('dotclear.jsUpload.msg.cancel',__('Cancel')). 766 self::jsVar('dotclear.jsUpload.msg.clean',__('Clean')). 767 self::jsVar('dotclear.jsUpload.msg.upload',__('Upload')). 768 self::jsVar('dotclear.jsUpload.msg.no_file_in_queue',__('No file in queue.')). 769 self::jsVar('dotclear.jsUpload.msg.file_in_queue',__('1 file in queue.')). 770 self::jsVar('dotclear.jsUpload.msg.files_in_queue',__('%d files in queue.')). 771 self::jsVar('dotclear.jsUpload.msg.queue_error',__('Queue error:')). 772 self::jsVar('dotclear.jsUpload.base_url',$base_url). 773 "\n//]]>\n". 774 "</script>\n"; 775 } 776 777 public static function jsToolMan() 778 { 779 return 780 '<script type="text/javascript" src="js/tool-man/core.js"></script>'. 781 '<script type="text/javascript" src="js/tool-man/events.js"></script>'. 782 '<script type="text/javascript" src="js/tool-man/css.js"></script>'. 783 '<script type="text/javascript" src="js/tool-man/coordinates.js"></script>'. 784 '<script type="text/javascript" src="js/tool-man/drag.js"></script>'. 785 '<script type="text/javascript" src="js/tool-man/dragsort.js"></script>'. 786 '<script type="text/javascript" src="js/dragsort-tablerows.js"></script>'; 787 } 788 789 public static function jsMetaEditor() 790 { 791 return 792 '<script type="text/javascript" src="js/meta-editor.js"></script>'; 793 } 524 self::jsLoad('js/jsUpload/vendor/jquery.ui.widget.js'). 525 self::jsLoad('js/jsUpload/tmpl.js'). 526 self::jsLoad('js/jsUpload/load-image.js'). 527 self::jsLoad('js/jsUpload/jquery.iframe-transport.js'). 528 self::jsLoad('js/jsUpload/jquery.fileupload.js'). 529 self::jsLoad('js/jsUpload/jquery.fileupload-process.js'). 530 self::jsLoad('js/jsUpload/jquery.fileupload-resize.js'). 531 self::jsLoad('js/jsUpload/jquery.fileupload-ui.js'). 532 533 '<script type="text/javascript">'."\n". 534 "//<![CDATA[\n". 535 "dotclear.jsUpload = {};\n". 536 "dotclear.jsUpload.msg = {};\n". 537 self::jsVar('dotclear.jsUpload.msg.limit_exceeded',__('Limit exceeded.')). 538 self::jsVar('dotclear.jsUpload.msg.size_limit_exceeded',__('File size exceeds allowed limit.')). 539 self::jsVar('dotclear.jsUpload.msg.canceled',__('Canceled.')). 540 self::jsVar('dotclear.jsUpload.msg.http_error',__('HTTP Error:')). 541 self::jsVar('dotclear.jsUpload.msg.error',__('Error:')). 542 self::jsVar('dotclear.jsUpload.msg.choose_file',__('Choose file')). 543 self::jsVar('dotclear.jsUpload.msg.choose_files',__('Choose files')). 544 self::jsVar('dotclear.jsUpload.msg.cancel',__('Cancel')). 545 self::jsVar('dotclear.jsUpload.msg.clean',__('Clean')). 546 self::jsVar('dotclear.jsUpload.msg.upload',__('Upload')). 547 self::jsVar('dotclear.jsUpload.msg.no_file_in_queue',__('No file in queue.')). 548 self::jsVar('dotclear.jsUpload.msg.file_in_queue',__('1 file in queue.')). 549 self::jsVar('dotclear.jsUpload.msg.files_in_queue',__('%d files in queue.')). 550 self::jsVar('dotclear.jsUpload.msg.queue_error',__('Queue error:')). 551 self::jsVar('dotclear.jsUpload.base_url',$base_url). 552 "\n//]]>\n". 553 "</script>\n"; 554 } 555 556 public static function jsToolMan() 557 { 558 return 559 '<script type="text/javascript" src="js/tool-man/core.js"></script>'. 560 '<script type="text/javascript" src="js/tool-man/events.js"></script>'. 561 '<script type="text/javascript" src="js/tool-man/css.js"></script>'. 562 '<script type="text/javascript" src="js/tool-man/coordinates.js"></script>'. 563 '<script type="text/javascript" src="js/tool-man/drag.js"></script>'. 564 '<script type="text/javascript" src="js/tool-man/dragsort.js"></script>'. 565 '<script type="text/javascript" src="js/dragsort-tablerows.js"></script>'; 566 } 567 568 public static function jsMetaEditor() 569 { 570 return 571 '<script type="text/javascript" src="js/meta-editor.js"></script>'; 572 } 794 573 } 795 574 ?> -
inc/admin/prepend.php
r1302 r1315 4 4 # This file is part of Dotclear 2. 5 5 # 6 # Copyright (c) 2003-201 3Olivier Meunier & Association Dotclear6 # Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 284 284 # Set menu titles 285 285 286 $_menu['System']->title = __('System settings');286 $_menu['System']->title = __('System'); 287 287 $_menu['Blog']->title = __('Blog'); 288 $_menu['Plugins']->title = __(' Additional plugins');288 $_menu['Plugins']->title = __('Plugins'); 289 289 if (!$user_ui_nofavmenu) 290 290 $_menu['Favorites']->title = __('My favorites'); … … 375 375 } 376 376 } 377 378 # Add admin default templates path 379 $core->tpl->getLoader()->addPath(dirname(__FILE__).'/default-templates'); 380 # Set admin context 381 $_ctx = new dcAdminContext($core); 382 $core->tpl->addExtension($_ctx); 383 384 # --BEHAVIOR-- adminPrepend 385 $core->callBehavior('adminPrepend',$core,$_ctx); 377 386 ?> -
inc/core/class.dc.blog.php
r1280 r1315 4 4 # This file is part of Dotclear 2. 5 5 # 6 # Copyright (c) 2003-201 3Olivier Meunier & Association Dotclear6 # Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 81 81 $this->desc = $b->blog_desc; 82 82 $this->url = $b->blog_url; 83 $this->host = http::getHostFromURL($this->url);83 $this->host = preg_replace('|^([a-z]{3,}://)(.*?)/.*$|','$1$2',$this->url); 84 84 $this->creadt = strtotime($b->blog_creadt); 85 85 $this->upddt = strtotime($b->blog_upddt); … … 805 805 806 806 if (!empty($params['user_id'])) { 807 $strReq .= "AND U.user_id = '".$this->con->escape($params['user_id'])."'";807 $strReq .= "AND U.user_id ".$this->con->in($params['user_id'])." "; 808 808 } 809 809 … … 889 889 $strReq .= 'ORDER BY post_dt DESC '; 890 890 } 891 } 892 893 if (!$count_only && !empty($params['limit'])) { 894 $strReq .= $this->con->limit($params['limit']); 891 if (!empty($params['limit'])) { 892 $strReq .= $this->con->limit($params['limit']); 893 } 895 894 } 896 895 -
inc/core/class.dc.core.php
r1179 r1315 4 4 # This file is part of Dotclear 2. 5 5 # 6 # Copyright (c) 2003-201 3Olivier Meunier & Association Dotclear6 # Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 39 39 public $rest; ///< <b>dcRestServer</b> dcRestServer object 40 40 public $log; ///< <b>dcLog</b> dcLog object 41 public $tpl; ///< <b>Twig_Environment</b> Twig_Environment object 41 42 42 43 private $versions = null; … … 95 96 $this->addFormater('xhtml', create_function('$s','return $s;')); 96 97 $this->addFormater('wiki', array($this,'wikiTransform')); 98 $this->loadTemplateEnvironment(); 97 99 } 98 100 … … 118 120 } 119 121 122 /** 123 Create template environment (Twig_Environment instance) 124 125 default-templates path must be added from admin|public/prepend.php with: 126 $core->tpl->getLoader()->addPath('PATH_TO/default-templates'); 127 Selected theme path must be added with: 128 $core->tpl->getLoader()->prependPath('PATH_TO/MY_THEME'); 129 */ 130 public function loadTemplateEnvironment() 131 { 132 $cache_dir = path::real(DC_TPL_CACHE.'/twtpl',false); 133 if (!is_dir($cache_dir)) { 134 try { 135 files::makeDir($cache_dir); 136 } catch (Exception $e) { 137 $cache_dir = false; 138 } 139 } 140 141 $this->tpl = new Twig_Environment( 142 new Twig_Loader_Filesystem(dirname(__FILE__).'/../swf'), 143 array( 144 'auto_reload' => true, 145 'autoescape' => false, 146 'base_template_class' => 'Twig_Template', 147 'cache' => $cache_dir, 148 'charset' => 'UTF-8', 149 'debug' => DC_DEBUG, 150 'optimizations' => -1, 151 'strict_variables' => 0 //DC_DEBUG // Please fix undefined variables! 152 ) 153 ); 154 $this->tpl->addExtension(new dcFormExtension($this)); 155 $this->tpl->addExtension(new dcTabExtension($this)); 156 } 120 157 121 158 /// @name Blog init methods -
inc/prepend.php
r1279 r1315 4 4 # This file is part of Dotclear 2. 5 5 # 6 # Copyright (c) 2003-201 3Olivier Meunier & Association Dotclear6 # Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 12 12 13 13 /* ------------------------------------------------------------------------------------------- */ 14 # ClearBricks, DotClear classes auto-loader14 # ClearBricks, Twig, DotClear classes auto-loader 15 15 if (@is_dir('/usr/lib/clearbricks')) { 16 16 define('CLEARBRICKS_PATH','/usr/lib/clearbricks'); … … 46 46 $__autoload['dcWorkspace'] = dirname(__FILE__).'/core/class.dc.workspace.php'; 47 47 $__autoload['dcPrefs'] = dirname(__FILE__).'/core/class.dc.prefs.php'; 48 $__autoload['dcTwigPage'] = dirname(__FILE__).'/core/class.dc.twig.page.php'; 48 49 49 50 $__autoload['rsExtPost'] = dirname(__FILE__).'/core/class.dc.rs.extensions.php'; … … 52 53 $__autoload['rsExtUser'] = dirname(__FILE__).'/core/class.dc.rs.extensions.php'; 53 54 55 $__autoload['dcAdminContext'] = dirname(__FILE__).'/admin/class.dc.admincontext.php'; 54 56 $__autoload['dcMenu'] = dirname(__FILE__).'/admin/class.dc.menu.php'; 55 57 $__autoload['dcPage'] = dirname(__FILE__).'/admin/lib.dc.page.php'; … … 63 65 $__autoload['context'] = dirname(__FILE__).'/public/lib.tpl.context.php'; 64 66 $__autoload['dcUrlHandlers'] = dirname(__FILE__).'/public/lib.urlhandlers.php'; 67 $__autoload['dcForm'] = dirname(__FILE__).'/admin/class.dc.form.php'; 68 $__autoload['dcFormExtension'] = dirname(__FILE__).'/admin/class.dc.form.php'; 69 $__autoload['dcTabExtension'] = dirname(__FILE__).'/admin/class.dc.tab.php'; 70 $__autoload['dcItemList'] = dirname(__FILE__).'/admin/class.dc.list.php'; 71 $__autoload['dcListFetcher'] = dirname(__FILE__).'/admin/class.dc.list.php'; 72 73 foreach (array('dcFilterSet', 'dcFilter','dcFilterCombo','dcFilterText','dcFilterBoolean') as $c) { 74 $__autoload[$c] = dirname(__FILE__).'/admin/class.dc.filter.php'; 75 } 65 76 66 77 # Clearbricks extensions 67 78 html::$absolute_regs[] = '/(<param\s+name="movie"\s+value=")(.*?)(")/msu'; 68 79 html::$absolute_regs[] = '/(<param\s+name="FlashVars"\s+value=".*?(?:mp3|flv)=)(.*?)(&|")/msu'; 80 81 if (@is_dir('/usr/lib/twig')) { 82 define('TWIG_PATH','/usr/lib/Twig'); 83 } elseif (is_dir(dirname(__FILE__).'/libs/Twig')) { 84 define('TWIG_PATH',dirname(__FILE__).'/libs/Twig'); 85 } elseif (isset($_SERVER['TWIG_PATH']) && is_dir($_SERVER['TWIG_PATH'])) { 86 define('TWIG_PATH',$_SERVER['TWIG_PATH']); 87 } 88 89 if (!defined('TWIG_PATH') || !is_dir(TWIG_PATH)) { 90 exit('No Twig path defined'); 91 } 92 require TWIG_PATH.'/Autoloader.php'; 93 Twig_Autoloader::register(); 94 69 95 /* ------------------------------------------------------------------------------------------- */ 70 96 … … 123 149 # Constants 124 150 define('DC_ROOT',path::real(dirname(__FILE__).'/..')); 125 define('DC_VERSION','2. 6-dev');151 define('DC_VERSION','2.99-dev'); 126 152 define('DC_DIGESTS',dirname(__FILE__).'/digests'); 127 153 define('DC_L10N_ROOT',dirname(__FILE__).'/../locales'); -
inc/public/lib.urlhandlers.php
r1128 r1315 4 4 # This file is part of Dotclear 2. 5 5 # 6 # Copyright (c) 2003-201 1Olivier Meunier & Association Dotclear6 # Copyright (c) 2003-2013 Olivier Meunier & Association Dotclear 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 86 86 $_ctx->nb_entry_per_page = $core->blog->settings->system->nb_post_per_page; 87 87 } 88 89 // Break public template here for now90 // just to check if template engine is well loaded.91 $core->tpl->display($tpl.'.twig');92 // To be continued...93 88 94 89 $tpl_file = $core->tpl->getFilePath($tpl); -
inc/public/prepend.php
r1128 r1315 4 4 # This file is part of Dotclear 2. 5 5 # 6 # Copyright (c) 2003-201 1Olivier Meunier & Association Dotclear6 # Copyright (c) 2003-2013 Olivier Meunier & Association Dotclear 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 55 55 } catch (Exception $e) {} 56 56 57 # Add public default templates path58 $core->tpl->getLoader()->addPath(dirname(__FILE__).'/default-templates');59 # Set public context60 $_ctx = new dcPublicContext($core);61 $core->tpl->addExtension($_ctx);62 63 /*64 57 # Creating template context 65 58 $_ctx = new context(); … … 71 64 ,640); 72 65 } 73 */ 66 74 67 # Loading locales 75 68 $_lang = $core->blog->settings->system->lang; … … 127 120 128 121 # --BEHAVIOR-- publicPrepend 129 $core->callBehavior('publicPrepend',$core ,$_ctx);122 $core->callBehavior('publicPrepend',$core); 130 123 131 124 # Prepare the HTTP cache thing … … 134 127 $mod_ts[] = $core->blog->upddt; 135 128 136 137 # Add parent theme path138 if ($__parent_theme && is_dir($core->blog->themes_path.'/'.$__parent_theme.'/tpl')) {139 $core->tpl->getLoader()->addPath($core->blog->themes_path.'/'.$__parent_theme.'/tpl');140 }141 # Add theme path at the begining of path list142 if (is_dir($core->blog->themes_path.'/'.$__theme.'/tpl')) {143 $core->tpl->getLoader()->prependPath($core->blog->themes_path.'/'.$__theme.'/tpl');144 }145 /*146 129 $__theme_tpl_path = array( 147 130 $core->blog->themes_path.'/'.$__theme.'/tpl' … … 155 138 dirname(__FILE__).'/default-templates', 156 139 $core->tpl->getPath()); 157 */ 140 158 141 $core->url->mode = $core->blog->settings->system->url_scan; 159 142 -
plugins/aboutConfig/_admin.php
r1294 r1315 4 4 # This file is part of Dotclear 2. 5 5 # 6 # Copyright (c) 2003-201 3Olivier Meunier & Association Dotclear6 # Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 12 12 if (!defined('DC_CONTEXT_ADMIN')) { return; } 13 13 14 $_menu[' System']->addItem('about:config','plugin.php?p=aboutConfig','index.php?pf=aboutConfig/icon.png',14 $_menu['Plugins']->addItem('about:config','plugin.php?p=aboutConfig','index.php?pf=aboutConfig/icon.png', 15 15 preg_match('/plugin.php\?p=aboutConfig(&.*)?$/',$_SERVER['REQUEST_URI']), 16 16 $core->auth->isSuperAdmin()); 17 18 $core->tpl->getLoader()->addPath(dirname(__FILE__).'/admtpl/','aboutConfig'); 17 19 ?> -
plugins/aboutConfig/index.php
r1312 r1315 4 4 # This file is part of Dotclear 2. 5 5 # 6 # Copyright (c) 2003-201 3Olivier Meunier & Association Dotclear6 # Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear 7 7 # Licensed under the GPL version 2.0 license. 8 8 # See LICENSE file or … … 12 12 if (!defined('DC_CONTEXT_ADMIN')) { return; } 13 13 14 # Local navigation 15 if (!empty($_POST['gs_nav'])) { 16 http::redirect($p_url.$_POST['gs_nav']); 17 exit; 18 } 19 if (!empty($_POST['ls_nav'])) { 20 http::redirect($p_url.$_POST['ls_nav']); 21 exit; 22 } 23 24 # Local settings update 25 if (!empty($_POST['s']) && is_array($_POST['s'])) 14 class adminPageAboutConfig 26 15 { 27 try 16 public static $p_url = 'plugin.php?p=aboutConfig'; 17 18 # Update local settings 19 public static function updLocal($form) 28 20 { 29 foreach ($_POST['s'] as $ns => $s) 30 { 31 $core->blog->settings->addNamespace($ns); 21 self::updSettings($form); 22 } 23 24 # Update global settings 25 public static function updGlobal($form) 26 { 27 self::updSettings($form,true); 28 } 29 30 # Update settings 31 protected static function updSettings($form,$global=false) 32 { 33 global $core,$_ctx; 34 35 $part = $global ? 'global' : 'local'; 36 $prefix = $part.'_'; 37 38 try { 39 foreach ($core->blog->settings->dumpNamespaces() as $ns => $namespace) { 40 $core->blog->settings->addNamespace($ns); 41 $ns_settings = $global ? 42 $namespace->dumpGlobalSettings() : $namespace->dumpSettings(); 43 44 foreach ($ns_settings as $k => $v) { 45 // need to cast type 46 $f = (string) $form->{$prefix.$ns.'_'.$k}; 47 settype($f,$v['type']); 48 49 $core->blog->settings->$ns->put($k,$f,null,null,true,$global); 50 $form->{$prefix.$ns.'_'.$k} = $f; 51 } 52 } 53 $core->blog->triggerBlog(); 32 54 33 foreach ($s as $k => $v) { 34 $core->blog->settings->$ns->put($k,$v); 35 } 36 37 $core->blog->triggerBlog(); 55 http::redirect(self::$p_url.'&upd=1&part='.$part); 56 } 57 catch (Exception $e) { 58 $_ctx->addError($e->getMessage()); 59 } 60 } 61 62 # Set nav and settings forms 63 public static function setForms($global=false) 64 { 65 global $core, $_ctx; 66 67 $prefix = $global ? 'global_' : 'local_'; 68 $action = $global ? 'updGlobal' : 'updLocal'; 69 70 if (!empty($_POST[$prefix.'nav'])) { 71 http::redirect(self::$p_url.$_POST[$prefix.'nav']); 72 exit; 38 73 } 39 74 40 http::redirect($p_url.'&upd=1'); 41 } 42 catch (Exception $e) 43 { 44 $core->error->add($e->getMessage()); 75 $nav_form = new dcForm($core,$prefix.'nav_form','plugin.php'); 76 $settings_form = new dcForm($core,$prefix.'settings_form','plugin.php'); 77 78 $settings = $combo = array(); 79 foreach ($core->blog->settings->dumpNamespaces() as $ns => $namespace) { 80 $ns_settings = $global ? 81 $namespace->dumpGlobalSettings() : $namespace->dumpSettings(); 82 83 foreach ($ns_settings as $k => $v) { 84 $settings[$ns][$k] = $v; 85 } 86 } 87 88 ksort($settings); 89 foreach ($settings as $ns => $s) { 90 $combo['#'.$prefix.$ns] = $ns; 91 ksort($s); 92 foreach ($s as $k => $v) { 93 if ($v['type'] == 'boolean') { 94 $settings_form->addField( 95 new dcFieldCombo($prefix.$ns.'_'.$k, 96 '',array(1 => __('yes'),0 => __('no')))); 97 } 98 else { 99 $settings_form->addField( 100 new dcFieldText($prefix.$ns.'_'.$k,'')); 101 } 102 $settings_form->{$prefix.$ns.'_'.$k} = $v['value']; 103 } 104 } 105 106 $nav_form 107 ->addField( 108 new dcFieldCombo($prefix.'nav','',$combo,array( 109 "label" => __('Goto:')))) 110 ->addField( 111 new dcFieldSubmit($prefix.'nav_submit',__('OK'))) 112 ->addField( 113 new dcFieldHidden ('p','aboutConfig')) 114 ; 115 116 $settings_form 117 ->addField( 118 new dcFieldSubmit($prefix.'submit',__('Save'),array( 119 'action' => array('adminPageAboutConfig',$action)))) 120 ->addField( 121 new dcFieldHidden ('p','aboutConfig')) 122 ; 123 124 $_ctx->{$prefix.'settings'} = $settings; 125 126 $nav_form->setup(); 127 $settings_form->setup(); 45 128 } 46 129 } 47 130 48 # Global settings update 49 if (!empty($_POST['gs']) && is_array($_POST['gs'])) 50 { 51 try 52 { 53 foreach ($_POST['gs'] as $ns => $s) 54 { 55 $core->blog->settings->addNamespace($ns); 56 57 foreach ($s as $k => $v) { 58 $core->blog->settings->$ns->put($k,$v,null,null,true,true); 59 } 60 61 $core->blog->triggerBlog(); 62 } 63 64 http::redirect($p_url.'&upd=1&part=global'); 65 } 66 catch (Exception $e) 67 { 68 $core->error->add($e->getMessage()); 69 } 131 # Local settings forms 132 adminPageAboutConfig::setForms(); 133 134 # Global settings forms 135 adminPageAboutConfig::setForms(true); 136 137 # Commons 138 if (!empty($_GET['upd'])) { 139 $_ctx->setAlert(__('Configuration successfully updated')); 70 140 } 71 72 $part = !empty($_GET['part']) && $_GET['part'] == 'global' ? 'global' : 'local'; 73 74 function settingLine($id,$s,$ns,$field_name,$strong_label) 75 { 76 if ($s['type'] == 'boolean') { 77 $field = form::combo(array($field_name.'['.$ns.']['.$id.']',$field_name.'_'.$id), 78 array(__('yes') => 1, __('no') => 0),$s['value'] ? 1 : 0); 79 } else { 80 $field = form::field(array($field_name.'['.$ns.']['.$id.']',$field_name.'_'.$id),40,null, 81 html::escapeHTML($s['value'])); 82 } 83 84 $slabel = $strong_label ? '<strong>%s</strong>' : '%s'; 85 86 return 87 '<tr>'. 88 '<td scope="raw"><label for="s_'.$id.'">'.sprintf($slabel,html::escapeHTML($id)).'</label></td>'. 89 '<td>'.$field.'</td>'. 90 '<td>'.$s['type'].'</td>'. 91 '<td>'.html::escapeHTML($s['label']).'</td>'. 92 '</tr>'; 141 if (!empty($_GET['upda'])) { 142 $_ctx->setAlert(__('Settings definition successfully updated')); 93 143 } 144 $_ctx->default_tab = !empty($_GET['part']) && $_GET['part'] == 'global' ? 'global' : 'local'; 145 $_ctx->fillPageTitle('about:config'); 146 $core->tpl->display('@aboutConfig/index.html.twig'); 94 147 ?> 95 <html>96 <head>97 <title>about:config</title>98 <?php echo dcPage::jsPageTabs($part); ?>99 <style type="text/css">100 table.settings { border: 1px solid #999; margin-bottom: 2em; }101 table.settings th { background: #f5f5f5; color: #444; padding-top: 0.3em; padding-bottom: 0.3em; }102 </style>103 <script type="text/javascript">104 //<![CDATA[105 $(function() {106 $("#gs_submit").hide();107 $("#ls_submit").hide();108 $("#gs_nav").change(function() {109 window.location = $("#gs_nav option:selected").val();110 })111 $("#ls_nav").change(function() {112 window.location = $("#ls_nav option:selected").val();113 })114 });115 //]]>116 </script>117 </head>118 119 <body>120 <?php121 if (!empty($_GET['upd'])) {122 dcPage::message(__('Configuration successfully updated'));123 }124 125 if (!empty($_GET['upda'])) {126 dcPage::message(__('Settings definition successfully updated'));127 }128 ?>129 <h2><?php echo __('System'); ?> › <span class="page-title">about:config</span></h2>130 131 <div id="local" class="multi-part" title="<?php echo sprintf(__('Settings for %s'),html::escapeHTML($core->blog->name)); ?>">132 133 134 <?php135 $table_header = '<table class="settings" id="%s"><caption>%s</caption>'.136 '<thead>'.137 '<tr>'."\n".138 ' <th class="nowrap">Setting ID</th>'."\n".139 ' <th>'.__('Value').'</th>'."\n".140 ' <th>'.__('Type').'</th>'."\n".141 ' <th class="maximalx">'.__('Description').'</th>'."\n".142 '</tr>'."\n".143 '</thead>'."\n".144 '<tbody>';145 $table_footer = '</tbody></table>';146 147 $settings = array();148 foreach ($core->blog->settings->dumpNamespaces() as $ns => $namespace) {149 foreach ($namespace->dumpSettings() as $k => $v) {150 $settings[$ns][$k] = $v;151 }152 }153 ksort($settings);154 if (count($settings) > 0) {155 $ns_combo = array();156 foreach ($settings as $ns => $s) {157 $ns_combo[$ns] = '#l_'.$ns;158 }159 echo160 '<form action="plugin.php" method="post">'.161 '<p class="anchor-nav">'.162 '<label for="ls_nav" class="classic">'.__('Goto:').'</label> '.form::combo('ls_nav',$ns_combo).163 ' <input type="submit" value="'.__('Ok').'" id="ls_submit" />'.164 '<input type="hidden" name="p" value="aboutConfig" />'.165 $core->formNonce().'</p></form>';166 }167 ?>168 169 <form action="plugin.php" method="post">170 171 <?php172 foreach ($settings as $ns => $s)173 {174 ksort($s);175 echo sprintf($table_header,'l_'.$ns,$ns);176 foreach ($s as $k => $v)177 {178 echo settingLine($k,$v,$ns,'s',!$v['global']);179 }180 echo $table_footer;181 }182 ?>183 184 <p><input type="submit" value="<?php echo __('Save'); ?>" />185 <input type="hidden" name="p" value="aboutConfig" />186 <?php echo $core->formNonce(); ?></p>187 </form>188 </div>189 190 <div id="global" class="multi-part" title="<?php echo __('global settings'); ?>">191 192 <?php193 $settings = array();194 195 foreach ($core->blog->settings->dumpNamespaces() as $ns => $namespace) {196 foreach ($namespace->dumpGlobalSettings() as $k => $v) {197 $settings[$ns][$k] = $v;198 }199 }200 201 ksort($settings);202 203 if (count($settings) > 0) {204 $ns_combo = array();205 foreach ($settings as $ns => $s) {206 $ns_combo[$ns] = '#g_'.$ns;207 }208 echo209 '<form action="plugin.php" method="post">'.210 '<p class="anchor-nav">'.211 '<label for="gs_nav" class="classic">'.__('Goto:').'</label> '.form::combo('gs_nav',$ns_combo).212 ' <input type="submit" value="'.__('Ok').'" id="gs_submit" />'.213 '<input type="hidden" name="p" value="aboutConfig" />'.214 $core->formNonce().'</p></form>';215 }216 ?>217 218 <form action="plugin.php" method="post">219 220 <?php221 foreach ($settings as $ns => $s)222 {223 ksort($s);224 echo sprintf($table_header,'g_'.$ns,$ns);225 foreach ($s as $k => $v)226 {227 echo settingLine($k,$v,$ns,'gs',false);228 }229 echo $table_footer;230 }231 ?>232 233 <p><input type="submit" value="<?php echo __('Save'); ?>" />234 <input type="hidden" name="p" value="aboutConfig" />235 <?php echo $core->formNonce(); ?></p>236 </form>237 </div>238 239 </body>240 </html>
Note: See TracChangeset
for help on using the changeset viewer.