Changeset 2609:c26642f775e2 for admin
- Timestamp:
- 12/10/13 09:00:09 (12 years ago)
- Branch:
- twig
- Parents:
- 2468:d7fda5a0bd39 (diff), 2608:3365c9df16a6 (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. - Location:
- admin
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
admin/auth.php
r2566 r2593 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 { 27 l10n::lang($dlang); 24 if ($dlang != 'en' && preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$dlang)) { 28 25 l10n::set(dirname(__FILE__).'/../locales/'.$dlang.'/main'); 29 26 } 30 31 $page_url = http::getHost().$_SERVER['REQUEST_URI'];32 33 $change_pwd = $core->auth->allowPassChange() && isset($_POST['new_pwd']) && isset($_POST['new_pwd_c']) && isset($_POST['login_data']);34 $login_data = !empty($_POST['login_data']) ? html::escapeHTML($_POST['login_data']) : null;35 $recover = $core->auth->allowPassChange() && !empty($_REQUEST['recover']);36 $safe_mode = !empty($_REQUEST['safe_mode']);37 $akey = $core->auth->allowPassChange() && !empty($_GET['akey']) ? $_GET['akey'] : null;38 $user_id = $user_pwd = $user_key = $user_email = null;39 $err = $msg = null;40 27 41 28 # Auto upgrade … … 44 31 try { 45 32 if (($changes = dotclearUpgrade($core)) !== false) { 46 $msg = __('Dotclear has been upgraded.').'<!-- '.$changes.' -->'; 47 } 48 } catch (Exception $e) { 49 $err = $e->getMessage(); 50 } 51 } 52 53 # If we have POST login informations, go throug auth process 54 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 55 45 { 56 $user_id = !empty($_POST['user_id']) ? $_POST['user_id'] : null; 57 $user_pwd = !empty($_POST['user_pwd']) ? $_POST['user_pwd'] : null; 58 } 59 # If we have COOKIE login informations, go throug auth process 60 elseif (isset($_COOKIE['dc_admin']) && strlen($_COOKIE['dc_admin']) == 104) 61 { 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 "maxlength" => 32))) 269 ->addField( 270 new dcFieldPassword('user_pwd','',array( 271 "label" => __('Password:')))) 272 ->addField( 273 new dcFieldText('user_email','',array( 274 "label" => __('Email:')))) 275 ->addField( 276 new dcFieldPassword('new_pwd','',array( 277 "label" => __('New password:')))) 278 ->addField( 279 new dcFieldPassword('new_pwd_c','',array( 280 "label" => __('Confirm password:')))) 281 ->addField( 282 new dcFieldCheckbox ('user_remember',1,array( 283 "label" => __('Remember my ID on this computer')))) 284 ->addField( 285 new dcFieldSubmit('auth_login',__('log in'),array( 286 'action' => array('adminPageAuth','login')))) 287 ->addField( 288 new dcFieldSubmit('auth_recover',__('recover'),array( 289 'action' => array('adminPageAuth','recover')))) 290 ->addField( 291 new dcFieldSubmit('auth_change',__('change'),array( 292 'action' => array('adminPageAuth','change')))) 293 ->addField( 294 new dcFieldHidden ('safe_mode','0')) 295 ->addField( 296 new dcFieldHidden ('recover','0')) 297 ->addField( 298 new dcFieldHidden ('login_data','')) 299 ->addField( 300 new dcFieldHidden ('blog','')); 301 302 # Context variables 303 $_ctx->allow_pass_change = $core->auth->allowPassChange(); 304 $_ctx->change_pwd = $core->auth->allowPassChange() && $form->new_pwd != '' && $form->new_pwd_c != '' && $form->login_data != ''; 305 $_ctx->recover = $form->recover = $core->auth->allowPassChange() && !empty($_REQUEST['recover']); 306 $_ctx->setSafeMode(!empty($_REQUEST['safe_mode'])); 307 $form->safe_mode = !empty($_REQUEST['safe_mode']); 308 $_ctx->akey = false; 309 $_ctx->dlang = $dlang; 310 311 # If we have no POST login informations and have COOKIE login informations, go throug auth process 312 if ($form->user_id == '' && $form->user_pwd == '' 313 && isset($_COOKIE['dc_admin']) && strlen($_COOKIE['dc_admin']) == 104) { 314 62 315 # If we have a remember cookie, go through auth process with user_key 63 316 $user_id = substr($_COOKIE['dc_admin'],40); 64 317 $user_id = @unpack('a32',@pack('H*',$user_id)); 65 if (is_array($user_id))66 {318 319 if (is_array($user_id)) { 67 320 $user_id = $user_id[1]; 68 321 $user_key = substr($_COOKIE['dc_admin'],0,40); 69 $user_pwd = null; 70 } 71 else 72 { 73 $user_id = null; 74 } 75 } 76 77 # Recover password 78 if ($recover && !empty($_POST['user_id']) && !empty($_POST['user_email'])) 79 { 80 $user_id = !empty($_POST['user_id']) ? $_POST['user_id'] : null; 81 $user_email = !empty($_POST['user_email']) ? $_POST['user_email'] : ''; 82 try 83 { 84 $recover_key = $core->auth->setRecoverKey($user_id,$user_email); 85 86 $subject = mail::B64Header('DotClear '.__('Password reset')); 87 $message = 88 __('Someone has requested to reset the password for the following site and username.')."\n\n". 89 $page_url."\n".__('Username:').' '.$user_id."\n\n". 90 __('To reset your password visit the following address, otherwise just ignore this email and nothing will happen.')."\n". 91 $page_url.'?akey='.$recover_key; 92 93 $headers[] = 'From: '.(defined('DC_ADMIN_MAILFROM') && DC_ADMIN_MAILFROM ? DC_ADMIN_MAILFROM : 'dotclear@local'); 94 $headers[] = 'Content-Type: text/plain; charset=UTF-8;'; 95 96 mail::sendMail($user_email,$subject,$message,$headers); 97 $msg = sprintf(__('The e-mail was sent successfully to %s.'),$user_email); 98 } 99 catch (Exception $e) 100 { 101 $err = $e->getMessage(); 102 } 103 } 104 # Send new password 105 elseif ($akey) 106 { 107 try 108 { 109 $recover_res = $core->auth->recoverUserPassword($akey); 110 111 $subject = mb_encode_mimeheader('DotClear '.__('Your new password'),'UTF-8','B'); 112 $message = 113 __('Username:').' '.$recover_res['user_id']."\n". 114 __('Password:').' '.$recover_res['new_pass']."\n\n". 115 preg_replace('/\?(.*)$/','',$page_url); 116 117 $headers[] = 'From: dotclear@'.$_SERVER['HTTP_HOST']; 118 $headers[] = 'Content-Type: text/plain; charset=UTF-8;'; 119 120 mail::sendMail($recover_res['user_email'],$subject,$message,$headers); 121 $msg = __('Your new password is in your mailbox.'); 122 } 123 catch (Exception $e) 124 { 125 $err = $e->getMessage(); 126 } 127 } 128 # Change password and retry to log 129 elseif ($change_pwd) 130 { 131 try 132 { 133 $tmp_data = explode('/',$_POST['login_data']); 134 if (count($tmp_data) != 3) { 135 throw new Exception(); 136 } 137 $data = array( 138 'user_id'=>base64_decode($tmp_data[0]), 139 'cookie_admin'=>$tmp_data[1], 140 'user_remember'=>$tmp_data[2]=='1' 141 ); 142 if ($data['user_id'] === false) { 143 throw new Exception(); 144 } 145 146 # Check login informations 147 $check_user = false; 148 if (isset($data['cookie_admin']) && strlen($data['cookie_admin']) == 104) 149 { 150 $user_id = substr($data['cookie_admin'],40); 151 $user_id = @unpack('a32',@pack('H*',$user_id)); 152 if (is_array($user_id)) 153 { 154 $user_id = $user_id[1]; 155 $user_key = substr($data['cookie_admin'],0,40); 156 $check_user = $core->auth->checkUser($user_id,null,$user_key) === true; 157 } 158 } 159 160 if (!$core->auth->allowPassChange() || !$check_user) { 161 $change_pwd = false; 162 throw new Exception(); 163 } 164 165 if ($_POST['new_pwd'] != $_POST['new_pwd_c']) { 166 throw new Exception(__("Passwords don't match")); 167 } 168 169 if ($core->auth->checkUser($user_id,$_POST['new_pwd']) === true) { 170 throw new Exception(__("You didn't change your password.")); 171 } 172 173 $cur = $core->con->openCursor($core->prefix.'user'); 174 $cur->user_change_pwd = 0; 175 $cur->user_pwd = $_POST['new_pwd']; 176 $core->updUser($core->auth->userID(),$cur); 177 178 $core->session->start(); 179 $_SESSION['sess_user_id'] = $user_id; 180 $_SESSION['sess_browser_uid'] = http::browserUID(DC_MASTER_KEY); 181 182 if ($data['user_remember']) 183 { 184 setcookie('dc_admin',$data['cookie_admin'],strtotime('+15 days'),'','',DC_ADMIN_SSL); 185 } 186 187 http::redirect('index.php'); 188 } 189 catch (Exception $e) 190 { 191 $err = $e->getMessage(); 192 } 193 } 194 # Try to log 195 elseif ($user_id !== null && ($user_pwd !== null || $user_key !== null)) 196 { 197 # We check the user 198 $check_user = $core->auth->checkUser($user_id,$user_pwd,$user_key,false) === true; 199 if ($check_user) { 200 $check_perms = $core->auth->findUserBlog() !== false; 201 } else { 202 $check_perms = false; 203 } 204 205 $cookie_admin = http::browserUID(DC_MASTER_KEY.$user_id. 206 crypt::hmac(DC_MASTER_KEY,$user_pwd)).bin2hex(pack('a32',$user_id)); 207 208 if ($check_perms && $core->auth->mustChangePassword()) 209 { 210 $login_data = join('/',array( 211 base64_encode($user_id), 212 $cookie_admin, 213 empty($_POST['user_remember'])?'0':'1' 214 )); 215 216 if (!$core->auth->allowPassChange()) { 217 $err = __('You have to change your password before you can login.'); 218 } else { 219 $err = __('In order to login, you have to change your password now.'); 220 $change_pwd = true; 221 } 222 } 223 elseif ($check_perms && !empty($_POST['safe_mode']) && !$core->auth->isSuperAdmin()) 224 { 225 $err = __('Safe Mode can only be used for super administrators.'); 226 } 227 elseif ($check_perms) 228 { 229 $core->session->start(); 230 $_SESSION['sess_user_id'] = $user_id; 231 $_SESSION['sess_browser_uid'] = http::browserUID(DC_MASTER_KEY); 232 233 if (!empty($_POST['blog'])) { 234 $_SESSION['sess_blog_id'] = $_POST['blog']; 235 } 236 237 if (!empty($_POST['safe_mode']) && $core->auth->isSuperAdmin()) { 238 $_SESSION['sess_safe_mode'] = true; 239 } 240 241 if (!empty($_POST['user_remember'])) { 242 setcookie('dc_admin',$cookie_admin,strtotime('+15 days'),'','',DC_ADMIN_SSL); 243 } 244 245 http::redirect('index.php'); 246 } 247 else 248 { 249 if (isset($_COOKIE['dc_admin'])) { 250 unset($_COOKIE['dc_admin']); 251 setcookie('dc_admin',false,-600,'','',DC_ADMIN_SSL); 252 } 253 if ($check_user) { 254 $err = __('Insufficient permissions'); 255 } else { 256 $err = __('Wrong username or password'); 257 } 258 } 322 $user_pwd = ''; 323 324 adminPageAuth::process($form,$user_id,$user_pwd,$user_key); 325 } 326 } 327 # If we have an akey, go throug send password process 328 elseif ($core->auth->allowPassChange() && !empty($_GET['akey'])) { 329 adminPageAuth::send($_GET['akey']); 259 330 } 260 331 261 332 if (isset($_GET['user'])) { 262 $user_id = $_GET['user']; 263 } 264 265 header('Content-Type: text/html; charset=UTF-8'); 333 $form->user_id = $_GET['user']; 334 } 335 336 $form->setup(); 337 338 $core->tpl->display('auth.html.twig'); 266 339 ?> 267 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">268 <html xmlns="http://www.w3.org/1999/xhtml"269 xml:lang="<?php echo $dlang; ?>" lang="<?php echo $dlang; ?>">270 <head>271 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />272 <meta http-equiv="Content-Script-Type" content="text/javascript" />273 <meta http-equiv="Content-Style-Type" content="text/css" />274 <meta http-equiv="Content-Language" content="<?php echo $dlang; ?>" />275 <meta name="ROBOTS" content="NOARCHIVE,NOINDEX,NOFOLLOW" />276 <meta name="GOOGLEBOT" content="NOSNIPPET" />277 <meta name="viewport" content="width=device-width, initial-scale=1.0" />278 <title><?php echo html::escapeHTML(DC_VENDOR_NAME); ?></title>279 <link rel="icon" type="image/png" href="images/favicon96-logout.png" />280 <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />281 282 283 <?php284 echo dcPage::jsLoadIE7();285 echo dcPage::jsCommon();286 ?>287 288 <link rel="stylesheet" href="style/default.css" type="text/css" media="screen" />289 290 <?php291 # --BEHAVIOR-- loginPageHTMLHead292 $core->callBehavior('loginPageHTMLHead');293 ?>294 295 <script type="text/javascript">296 //<![CDATA[297 $(window).load(function() {298 var uid = $('input[name=user_id]');299 var upw = $('input[name=user_pwd]');300 uid.focus();301 302 if (upw.length == 0) { return; }303 304 uid.keypress(processKey);305 306 function processKey(evt) {307 if (evt.which == 13 && upw.val() == '') {308 upw.focus();309 return false;310 }311 return true;312 };313 $.cookie('dc_admin_test_cookie',true);314 if ($.cookie('dc_admin_test_cookie')) {315 $('#cookie_help').hide();316 $.cookie('dc_admin_test_cookie', '', {'expires': -1});317 } else {318 $('#cookie_help').show();319 }320 $('#issue #more').toggleWithLegend($('#issue').children().not('#more'));321 });322 //]]>323 </script>324 </head>325 326 <body id="dotclear-admin" class="auth">327 328 <form action="auth.php" method="post" id="login-screen">329 <h1><?php echo html::escapeHTML(DC_VENDOR_NAME); ?></h1>330 331 <?php332 if ($err) {333 echo '<div class="error">'.$err.'</div>';334 }335 if ($msg) {336 echo '<p class="success">'.$msg.'</p>';337 }338 339 if ($akey)340 {341 echo '<p><a href="auth.php">'.__('Back to login screen').'</a></p>';342 }343 elseif ($recover)344 {345 echo346 '<div class="fieldset"><h2>'.__('Request a new password').'</h2>'.347 '<p><label for="user_id">'.__('Username:').'</label> '.348 form::field(array('user_id','user_id'),20,32,html::escapeHTML($user_id)).'</p>'.349 350 '<p><label for="user_email">'.__('Email:').'</label> '.351 form::field(array('user_email','user_email'),20,255,html::escapeHTML($user_email)).'</p>'.352 353 '<p><input type="submit" value="'.__('recover').'" />'.354 form::hidden(array('recover'),1).'</p>'.355 '</div>'.356 357 '<div id="issue">'.358 '<p><a href="auth.php">'.__('Back to login screen').'</a></p>'.359 '</div>';360 }361 elseif ($change_pwd)362 {363 echo364 '<div class="fieldset"><h2>'.__('Change your password').'</h2>'.365 '<p><label for="new_pwd">'.__('New password:').'</label> '.366 form::password(array('new_pwd','new_pwd'),20,255).'</p>'.367 368 '<p><label for="new_pwd_c">'.__('Confirm password:').'</label> '.369 form::password(array('new_pwd_c','new_pwd_c'),20,255).'</p>'.370 '</div>'.371 372 '<p><input type="submit" value="'.__('change').'" />'.373 form::hidden('login_data',$login_data).'</p>';374 }375 else376 {377 if (is_callable(array($core->auth,'authForm')))378 {379 echo $core->auth->authForm($user_id);380 }381 else382 {383 if ($safe_mode) {384 echo '<div class="fieldset">';385 echo '<h2>'.__('Safe mode login').'</h2>';386 echo387 '<p class="form-note">'.388 __('This mode allows you to login without activating any of your plugins. This may be useful to solve compatibility problems').' </p>'.389 '<p class="form-note">'.__('Disable or delete any plugin suspected to cause trouble, then log out and log back in normally.').390 '</p>';391 }392 else {393 echo '<div class="fieldset">';394 }395 396 echo397 '<p><label for="user_id">'.__('Username:').'</label> '.398 form::field(array('user_id','user_id'),20,32,html::escapeHTML($user_id)).'</p>'.399 400 '<p><label for="user_pwd">'.__('Password:').'</label> '.401 form::password(array('user_pwd','user_pwd'),20,255).'</p>'.402 403 '<p>'.404 form::checkbox(array('user_remember','user_remember'),1).405 '<label for="user_remember" class="classic">'.406 __('Remember my ID on this computer').'</label></p>'.407 408 '<p><input type="submit" value="'.__('log in').'" class="login" /></p>';409 410 if (!empty($_REQUEST['blog'])) {411 echo form::hidden('blog',html::escapeHTML($_REQUEST['blog']));412 }413 if($safe_mode) {414 echo415 form::hidden('safe_mode',1).416 '</div>';417 }418 else {419 echo '</div>';420 }421 echo422 '<p id="cookie_help" class="error">'.__('You must accept cookies in order to use the private area.').'</p>';423 424 echo '<div id="issue">';425 426 if ($safe_mode) {427 echo428 '<p><a href="auth.php" id="normal_mode_link">'.__('Get back to normal authentication').'</a></p>';429 } else {430 echo '<p id="more"><strong>'.__('Connection issue?').'</strong></p>';431 if ($core->auth->allowPassChange()) {432 echo '<p><a href="auth.php?recover=1">'.__('I forgot my password').'</a></p>';433 }434 echo '<p><a href="auth.php?safe_mode=1" id="safe_mode_link">'.__('I want to log in in safe mode').'</a></p>';435 }436 437 echo '</div>';438 }439 }440 ?>441 </form>442 </body>443 </html> -
admin/index.php
r2566 r2593 15 15 exit; 16 16 } 17 if (!empty($_GET['tf'])) { 18 define('DC_CONTEXT_ADMIN',true); 19 require dirname(__FILE__).'/../inc/load_theme_file.php'; 20 exit; 21 } 17 22 18 23 require dirname(__FILE__).'/../inc/admin/prepend.php'; … … 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 } 59 if (!$core->auth->user_prefs->dashboard->prefExists('quickentry')) { 60 if (!$core->auth->user_prefs->dashboard->prefExists('quickentry',true)) { 61 $core->auth->user_prefs->dashboard->put('quickentry',false,'boolean','',null,true); 62 } 63 $core->auth->user_prefs->dashboard->put('quickentry',false,'boolean'); 64 } 65 66 // Handle folded/unfolded sections in admin from user preferences 67 $ws = $core->auth->user_prefs->addWorkspace('toggles'); 68 if (!$core->auth->user_prefs->toggles->prefExists('unfolded_sections')) { 69 $core->auth->user_prefs->toggles->put('unfolded_sections','','string','Folded sections in admin',null,true); 70 } 71 72 73 # Dashboard icons 74 $__dashboard_icons = new ArrayObject(); 75 76 $favs = $core->favs->getUserFavorites(); 77 $core->favs->appendDashboardIcons($__dashboard_icons); 78 79 # Check plugins and themes update from repository 80 function dc_check_store_update($mod, $url, $img, $icon) 81 { 82 $repo = new dcStore($mod, $url); 83 $upd = $repo->get(true); 84 if (!empty($upd)) { 85 $icon[0] .= '<br />'.sprintf(__('An update is available', '%s updates are available.', count($upd)),count($upd)); 86 $icon[1] .= '#update'; 87 $icon[2] = 'images/menu/'.$img.'-b-update.png'; 88 } 89 } 90 if (isset($__dashboard_icons['plugins'])) { 91 dc_check_store_update($core->plugins, $core->blog->settings->system->store_plugin_url, 'plugins', $__dashboard_icons['plugins']); 92 } 93 if (isset($__dashboard_icons['blog_theme'])) { 94 $themes = new dcThemes($core); 95 $themes->loadModules($core->blog->themes_path, null); 96 dc_check_store_update($themes, $core->blog->settings->system->store_theme_url, 'blog-theme', $__dashboard_icons['blog_theme']); 97 } 98 99 # Latest news for dashboard 100 $__dashboard_items = new ArrayObject(array(new ArrayObject(),new ArrayObject())); 101 102 $dashboardItem = 0; 103 104 if ($core->auth->user_prefs->dashboard->dcnews) { 101 102 # Send dcnews to templates 103 $_ctx->dashboard_dcnews = array(); 104 if ($core->auth->user_prefs->dashboard->dcnews && !empty($__resources['rss_news'])) { 105 105 try 106 106 { 107 if (empty($__resources['rss_news'])) {108 throw new Exception();109 }110 111 107 $feed_reader = new feedReader; 112 108 $feed_reader->setCacheDir(DC_TPL_CACHE); … … 114 110 $feed_reader->setUserAgent('Dotclear - http://www.dotclear.org/'); 115 111 $feed = $feed_reader->parse($__resources['rss_news']); 116 if ($feed) 117 { 118 $latest_news = '<div class="box medium dc-box"><h3>'.__('Dotclear news').'</h3><dl id="news">'; 112 if ($feed) { 113 $items = array(); 119 114 $i = 1; 120 foreach ($feed->items as $item) 121 { 122 $dt = isset($item->link) ? '<a href="'.$item->link.'" class="outgoing" title="'.$item->title.'">'. 123 $item->title.' <img src="images/outgoing-blue.png" alt="" /></a>' : $item->title; 124 125 if ($i < 3) { 126 $latest_news .= 127 '<dt>'.$dt.'</dt>'. 128 '<dd><p><strong>'.dt::dt2str(__('%d %B %Y:'),$item->pubdate,'Europe/Paris').'</strong> '. 129 '<em>'.text::cutString(html::clean($item->content),120).'...</em></p></dd>'; 130 } else { 131 $latest_news .= 132 '<dt>'.$dt.'</dt>'. 133 '<dd>'.dt::dt2str(__('%d %B %Y:'),$item->pubdate,'Europe/Paris').'</dd>'; 134 } 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 ); 135 122 $i++; 136 if ($i > 2) { break; }123 if ($i > 3) { break; } 137 124 } 138 $latest_news .= '</dl></div>'; 139 $__dashboard_items[$dashboardItem][] = $latest_news; 140 $dashboardItem++; 125 $_ctx->dashboard_dcnews = $items; 141 126 } 142 127 } … … 144 129 } 145 130 146 # Documentation links 147 if ($core->auth->user_prefs->dashboard->doclinks) { 148 if (!empty($__resources['doc'])) 149 { 150 $doc_links = '<div class="box small dc-box"><h3>'.__('Documentation and support').'</h3><ul>'; 151 152 foreach ($__resources['doc'] as $k => $v) { 153 $doc_links .= '<li><a class="outgoing" href="'.$v.'" title="'.$k.'">'.$k. 154 ' <img src="images/outgoing-blue.png" alt="" /></a></li>'; 155 } 156 157 $doc_links .= '</ul></div>'; 158 $__dashboard_items[$dashboardItem][] = $doc_links; 159 $dashboardItem++; 160 } 161 } 162 131 # Quick entry prefs 132 if (!$core->auth->user_prefs->dashboard->prefExists('quickentry')) { 133 if (!$core->auth->user_prefs->dashboard->prefExists('quickentry',true)) { 134 $core->auth->user_prefs->dashboard->put('quickentry',true,'boolean','',null,true); 135 } 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; 188 } 189 190 # Dashboard icons 191 $__dashboard_icons = new ArrayObject(); 192 193 # Dashboard favorites 194 $post_count = $core->blog->getPosts(array(),true)->f(0); 195 $str_entries = ($post_count > 1) ? __('%d entries') : __('%d entry'); 196 197 $comment_count = $core->blog->getComments(array(),true)->f(0); 198 $str_comments = ($comment_count > 1) ? __('%d comments') : __('%d comment'); 199 200 $ws = $core->auth->user_prefs->addWorkspace('favorites'); 201 $count = 0; 202 foreach ($ws->dumpPrefs() as $k => $v) { 203 // User favorites only 204 if (!$v['global']) { 205 $fav = unserialize($v['value']); 206 if (($fav['permissions'] == '*') || $core->auth->check($fav['permissions'],$core->blog->id)) { 207 if (dc_valid_fav($fav['url'])) { 208 $count++; 209 $title = ($fav['name'] == 'posts' ? sprintf($str_entries,$post_count) : 210 ($fav['name'] == 'comments' ? sprintf($str_comments,$comment_count) : $fav['title'])); 211 $__dashboard_icons[$fav['name']] = new ArrayObject(array(__($title),$fav['url'],$fav['large-icon'])); 212 213 # Let plugins set their own title for favorite on dashboard 214 $core->callBehavior('adminDashboardFavsIcon',$core,$fav['name'],$__dashboard_icons[$fav['name']]); 215 } 216 } 217 } 218 } 219 if (!$count) { 220 // Global favorites if any 221 foreach ($ws->dumpPrefs() as $k => $v) { 222 $fav = unserialize($v['value']); 223 if (($fav['permissions'] == '*') || $core->auth->check($fav['permissions'],$core->blog->id)) { 224 if (dc_valid_fav($fav['url'])) { 225 $count++; 226 $title = ($fav['name'] == 'posts' ? sprintf($str_entries,$post_count) : 227 ($fav['name'] == 'comments' ? sprintf($str_comments,$comment_count) : $fav['title'])); 228 $__dashboard_icons[$fav['name']] = new ArrayObject(array(__($title),$fav['url'],$fav['large-icon'])); 229 230 # Let plugins set their own title for favorite on dashboard 231 $core->callBehavior('adminDashboardFavsIcon',$core,$fav['name'],$__dashboard_icons[$fav['name']]); 232 } 233 } 234 } 235 } 236 if (!$count) { 237 // No user or global favorites, add "user pref" and "new entry" fav 238 if ($core->auth->check('usage,contentadmin',$core->blog->id)) { 239 $__dashboard_icons['new_post'] = new ArrayObject(array(__('New entry'),'post.php','images/menu/edit-b.png')); 240 } 241 $__dashboard_icons['prefs'] = new ArrayObject(array(__('My preferences'),'preferences.php','images/menu/user-pref-b.png')); 242 } 243 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 256 $__dashboard_items = new ArrayObject(array(new ArrayObject,new ArrayObject)); 163 257 $core->callBehavior('adminDashboardItems', $core, $__dashboard_items); 164 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 165 270 # Dashboard content 166 $dashboardContents = '';167 271 $__dashboard_contents = new ArrayObject(array(new ArrayObject,new ArrayObject)); 168 272 $core->callBehavior('adminDashboardContents', $core, $__dashboard_contents); 169 273 170 /* DISPLAY 171 -------------------------------------------------------- */ 172 dcPage::open(__('Dashboard'), 173 dcPage::jsToolBar(). 174 dcPage::jsLoad('js/_index.js'). 175 # --BEHAVIOR-- adminDashboardHeaders 176 $core->callBehavior('adminDashboardHeaders'), 177 dcPage::breadcrumb( 178 array( 179 __('Dashboard').' : '.html::escapeHTML($core->blog->name) => '' 180 ), 181 array('home_link' =>false) 182 ) 183 ); 184 185 # Dotclear updates notifications 186 if ($core->auth->isSuperAdmin() && is_readable(DC_DIGESTS)) 187 { 188 $updater = new dcUpdate(DC_UPDATE_URL,'dotclear',DC_UPDATE_VERSION,DC_TPL_CACHE.'/versions'); 189 $new_v = $updater->check(DC_VERSION); 190 $version_info = $new_v ? $updater->getInfoURL() : ''; 191 192 if ($updater->getNotify() && $new_v) { 193 echo 194 '<div class="dc-update"><h3>'.sprintf(__('Dotclear %s is available!'),$new_v).'</h3> '. 195 '<p><a class="button submit" href="update.php">'.sprintf(__('Upgrade now'),$new_v).'</a> '. 196 '<a class="button" href="update.php?hide_msg=1">'.__('Remind me later').'</a>'. 197 ($version_info ? ' </p>'. 198 '<p class="updt-info"><a href="'.$version_info.'">'.__('Information about this version').'</a>' : '').'</p>'. 199 '</div>'; 200 } 201 } 202 203 if ($core->auth->getInfo('user_default_blog') != $core->blog->id && $core->auth->getBlogCount() > 1) { 204 echo 205 '<p><a href="index.php?default_blog=1" class="button">'.__('Make this blog my default blog').'</a></p>'; 206 } 207 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 208 286 if ($core->blog->status == 0) { 209 echo '<p class="static-msg">'.__('This blog is offline').'.</p>';287 $_ctx->addMessageStatic(__('This blog is offline')); 210 288 } elseif ($core->blog->status == -1) { 211 echo '<p class="static-msg">'.__('This blog is removed').'.</p>'; 212 } 213 289 $_ctx->addMessageStatic(__('This blog is removed')); 290 } 291 292 # Config errors messages 214 293 if (!defined('DC_ADMIN_URL') || !DC_ADMIN_URL) { 215 echo 216 '<p class="static-msg">'. 217 sprintf(__('%s is not defined, you should edit your configuration file.'),'DC_ADMIN_URL'). 218 ' '.__('See <a href="http://dotclear.org/documentation/2.0/admin/config">documentation</a> for more information.'). 219 '</p>'; 220 } 221 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 } 222 299 if (!defined('DC_ADMIN_MAILFROM') || !DC_ADMIN_MAILFROM) { 223 echo 224 '<p class="static-msg">'. 225 sprintf(__('%s is not defined, you should edit your configuration file.'),'DC_ADMIN_MAILFROM'). 226 ' '.__('See <a href="http://dotclear.org/documentation/2.0/admin/config">documentation</a> for more information.'). 227 '</p>'; 228 } 229 230 $err = array(); 231 232 # Check cache directory 233 if ( $core->auth->isSuperAdmin() ) { 234 if (!is_dir(DC_TPL_CACHE) || !is_writable(DC_TPL_CACHE)) { 235 $err[] = '<p>'.__("The cache directory does not exist or is not writable. You must create this directory with sufficient rights and affect this location to \"DC_TPL_CACHE\" in inc/config.php file.").'</p>'; 236 } 237 } else { 238 if (!is_dir(DC_TPL_CACHE) || !is_writable(DC_TPL_CACHE)) { 239 $err[] = '<p>'.__("The cache directory does not exist or is not writable. You should contact your administrator.").'</p>'; 240 } 241 } 242 243 # Check public directory 244 if ( $core->auth->isSuperAdmin() ) { 245 if (!is_dir($core->blog->public_path) || !is_writable($core->blog->public_path)) { 246 $err[] = '<p>'.__("There is no writable directory /public/ at the location set in about:config \"public_path\". You must create this directory with sufficient rights (or change this setting).").'</p>'; 247 } 248 } else { 249 if (!is_dir($core->blog->public_path) || !is_writable($core->blog->public_path)) { 250 $err[] = '<p>'.__("There is no writable root directory for the media manager. You should contact your administrator.").'</p>'; 251 } 252 } 253 254 # Error list 255 if (count($err) > 0) { 256 echo '<div class="error"><p><strong>'.__('Error:').'</strong></p>'. 257 '<ul><li>'.implode("</li><li>",$err).'</li></ul></div>'; 258 } 259 260 # Plugins install messages 261 if (!empty($plugins_install['success'])) 262 { 263 echo '<div class="success">'.__('Following plugins have been installed:').'<ul>'; 264 foreach ($plugins_install['success'] as $k => $v) { 265 echo '<li>'.$k.'</li>'; 266 } 267 echo '</ul></div>'; 268 } 269 if (!empty($plugins_install['failure'])) 270 { 271 echo '<div class="error">'.__('Following plugins have not been installed:').'<ul>'; 272 foreach ($plugins_install['failure'] as $k => $v) { 273 echo '<li>'.$k.' ('.$v.')</li>'; 274 } 275 echo '</ul></div>'; 276 } 277 # Errors modules notifications 278 if ($core->auth->isSuperAdmin()) 279 { 280 $list = $core->plugins->getErrors(); 281 if (!empty($list)) { 282 echo 283 '<div class="error" id="module-errors" class="error"><p>'.__('Errors have occured with following plugins:').'</p> '. 284 '<ul><li>'.implode("</li>\n<li>", $list).'</li></ul></div>'; 285 } 286 } 287 288 # Dashboard columns (processed first, as we need to know the result before displaying the icons.) 289 $dashboardItems = ''; 290 291 foreach ($__dashboard_items as $i) 292 { 293 if ($i->count() > 0) 294 { 295 $dashboardItems .= ''; 296 foreach ($i as $v) { 297 $dashboardItems .= $v; 298 } 299 $dashboardItems .= ''; 300 } 301 } 302 303 # Dashboard elements 304 echo '<div id="dashboard-main">'; 305 306 # Dashboard icons 307 echo '<div id="icons">'; 308 foreach ($__dashboard_icons as $i) 309 { 310 echo 311 '<p><a href="'.$i[1].'"><img src="'.dc_admin_icon_url($i[2]).'" alt="" />'. 312 '<br /><span>'.$i[0].'</span></a></p>'; 313 } 314 echo '</div>'; 315 316 if ($core->auth->user_prefs->dashboard->quickentry) { 317 if ($core->auth->check('usage,contentadmin',$core->blog->id)) 318 { 319 # Getting categories 320 $categories_combo = dcAdminCombos::getCategoriesCombo( 321 $core->blog->getCategories(array('post_type'=>'post')) 322 ); 323 324 echo 325 '<div id="quick">'. 326 '<h3>'.__('Quick entry').'</h3>'. 327 '<form id="quick-entry" action="post.php" method="post" class="fieldset">'. 328 '<h4>'.__('New entry').'</h4>'. 329 '<p class="col"><label for="post_title" class="required"><abbr title="'.__('Required field').'">*</abbr> '.__('Title:').'</label>'. 330 form::field('post_title',20,255,'','maximal'). 331 '</p>'. 332 '<p class="area"><label class="required" '. 333 'for="post_content"><abbr title="'.__('Required field').'">*</abbr> '.__('Content:').'</label> '. 334 form::textarea('post_content',50,10). 335 '</p>'. 336 '<p><label for="cat_id" class="classic">'.__('Category:').'</label> '. 337 form::combo('cat_id',$categories_combo).'</p>'. 338 ($core->auth->check('categories', $core->blog->id) 339 ? '<div>'. 340 '<p id="new_cat" class="q-cat">'.__('Add a new category').'</p>'. 341 '<p class="q-cat"><label for="new_cat_title">'.__('Title:').'</label> '. 342 form::field('new_cat_title',30,255,'','').'</p>'. 343 '<p class="q-cat"><label for="new_cat_parent">'.__('Parent:').'</label> '. 344 form::combo('new_cat_parent',$categories_combo,'',''). 345 '</p>'. 346 '<p class="form-note info clear">'.__('This category will be created when you will save your post.').'</p>'. 347 '</div>' 348 : ''). 349 '<p><input type="submit" value="'.__('Save').'" name="save" /> '. 350 ($core->auth->check('publish',$core->blog->id) 351 ? '<input type="hidden" value="'.__('Save and publish').'" name="save-publish" />' 352 : ''). 353 $core->formNonce(). 354 form::hidden('post_status',-2). 355 form::hidden('post_format',$core->auth->getOption('post_format')). 356 form::hidden('post_excerpt',''). 357 form::hidden('post_lang',$core->auth->getInfo('user_lang')). 358 form::hidden('post_notes',''). 359 '</p>'. 360 '</form>'. 361 '</div>'; 362 } 363 } 364 365 foreach ($__dashboard_contents as $i) 366 { 367 if ($i->count() > 0) 368 { 369 $dashboardContents .= ''; 370 foreach ($i as $v) { 371 $dashboardContents .= $v; 372 } 373 $dashboardContents .= ''; 374 } 375 } 376 377 if ($dashboardContents != '' || $dashboardItems != '') { 378 echo 379 '<div id="dashboard-boxes">'. 380 '<div class="db-items">'.$dashboardItems.$dashboardContents.'</div>'. 381 '</div>'; 382 } 383 384 echo '</div>'; #end dashboard-main 385 dcPage::helpBlock('core_dashboard'); 386 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->setBreadCrumb(__('Dashboard').' : '.html::escapeHTML($core->blog->name), false); 307 $core->tpl->display('index.html.twig'); 308 ?> -
admin/js/_post.js
r2313 r2593 1 dotclear.commentExpander = function(line) { 2 var td = line.firstChild; 3 4 var img = document.createElement('img'); 5 img.src = dotclear.img_plus_src; 6 img.alt = dotclear.img_plus_alt; 7 img.className = 'expand'; 8 $(img).css('cursor','pointer'); 9 img.line = line; 10 img.onclick = function() { dotclear.viewCommentContent(this,this.line); }; 11 12 td.insertBefore(img,td.firstChild); 13 }; 14 15 dotclear.viewCommentContent = function(img,line) { 16 var commentId = line.id.substr(1); 17 1 dotclear.viewCommentContent = function(line,action) { 2 var commentId = $(line).attr('id').substr(1); 18 3 var tr = document.getElementById('ce'+commentId); 19 4 … … 26 11 tr.appendChild(td); 27 12 28 img.src = dotclear.img_minus_src;29 img.alt = dotclear.img_minus_alt;30 31 13 // Get comment content 32 14 $.get('services.php',{f:'getCommentById',id: commentId},function(data) { … … 60 42 $(tr).toggle(); 61 43 $(line).toggleClass('expand'); 62 img.src = dotclear.img_minus_src;63 img.alt = dotclear.img_minus_alt;64 44 } 65 45 else … … 67 47 $(tr).toggle(); 68 48 $(line).toggleClass('expand'); 69 img.src = dotclear.img_plus_src;70 img.alt = dotclear.img_plus_alt;71 49 } 72 50 }; … … 90 68 $(this).val(last_post_format); 91 69 } 92 70 93 71 $('.format_control > *').addClass('hide'); 94 72 $('.format_control:not(.control_no_'+$(this).val()+') > *').removeClass('hide'); … … 102 80 if (document.getElementById('comment_content')) { 103 81 var commentTb = new jsToolBar(document.getElementById('comment_content')); 82 commentTb.draw('xhtml'); 104 83 } 105 84 … … 128 107 a.className = 'button '; 129 108 $(a).click(function() { 130 109 131 110 excerpt_content = $('#post_excerpt').css('display') != 'none' ? $('#post_excerpt').val() : $('#excerpt-area iframe').contents().find('body').html(); 132 post_content 133 111 post_content = $('#post_content').css('display') != 'none' ? $('#post_content').val() : $('#content-area iframe').contents().find('body').html(); 112 134 113 var params = { 135 114 xd_check: dotclear.nonce, … … 146 125 return false; 147 126 } 148 127 149 128 $('.message, .success, .error, .warning-msg').remove(); 150 129 … … 152 131 var p = document.createElement('p'); 153 132 p.id = 'markup-validator'; 154 133 155 134 $(p).addClass('success'); 156 135 $(p).text(dotclear.msg.xhtml_valid); … … 162 141 var div = document.createElement('div'); 163 142 div.id = 'markup-validator'; 164 143 165 144 $(div).addClass('error'); 166 145 $(div).html('<p><strong>' + dotclear.msg.xhtml_not_valid + '</strong></p>' + $(data).find('errors').text()); … … 185 164 186 165 a.appendChild(document.createTextNode(dotclear.msg.xhtml_validator)); 187 166 188 167 $('.format_control > *').addClass('hide'); 189 168 $('.format_control:not(.control_no_'+last_post_format+') > *').removeClass('hide'); … … 266 245 267 246 $('#comments').onetabload(function() { 268 $('#form-comments .comments-list tr.line').each(function() { 269 dotclear.commentExpander(this); 247 $.expandContent({ 248 lines:$('#form-comments .comments-list tr.line'), 249 callback:dotclear.viewCommentContent 270 250 }); 271 251 $('#form-comments .checkboxes-helpers').each(function() { … … 277 257 278 258 $('#trackbacks').onetabload(function() { 279 $('#form-trackbacks .comments-list tr.line').each(function() { 280 dotclear.commentExpander(this); 259 $.expandContent({ 260 lines:$('#form-trackbacks .comments-list tr.line'), 261 callback:dotclear.viewCommentContent 281 262 }); 282 263 $('#form-trackbacks .checkboxes-helpers').each(function() { -
admin/plugin.php
r2566 r2593 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; … … 47 44 ob_end_clean(); 48 45 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 } 53 54 if (preg_match_all('|(<script.*?>.*?</script>)|ms',$m[1],$ms)) { 55 foreach ($ms[1] as $v) { 56 $p_head .= $v."\n"; 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 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 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 } 77 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 dcPage::breadcrumb( 85 array( 86 __('System') => '', 87 __('Plugin not found') => '' 88 )) 89 ); 90 91 echo '<p>'.__('The plugin you reached does not exist or does not have an admin page.').'</p>'; 92 93 call_user_func($close_f); 90 # No plugin or content found 91 if (!$has_content) { 92 $_ctx->setBreadcrumb(__('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'); 94 95 } 96 ?> -
admin/post.php
r2566 r2593 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 class PostActions 18 { 19 public static function savePost($form) { 20 global $_ctx, $core; 21 if (!$form->can_edit_post) { 22 return; 23 } 24 try { 25 $form->check($_ctx); 26 $form->cat_id = (integer) $form->cat_id; 27 28 if (!empty($form->post_dt)) { 29 try 30 { 31 $post_dt = strtotime($form->post_dt); 32 if ($post_dt == false || $post_dt == -1) { 33 $bad_dt = true; 34 throw new Exception(__('Invalid publication date')); 35 } 36 $form->post_dt = date('Y-m-d H:i',$post_dt); 37 } 38 catch (Exception $e) 39 { 40 $core->error->add($e->getMessage()); 41 } 42 } 43 $post_excerpt = $form->post_excerpt; 44 $post_content = $form->post_content; 45 $post_excerpt_xhtml = ''; 46 $post_content_xhtml = ''; 47 $core->blog->setPostContent( 48 $form->id,$form->post_format,$form->post_lang, 49 $post_excerpt,$post_excerpt_xhtml,$post_content,$post_content_xhtml 50 ); 51 $form->post_excerpt = $post_excerpt; 52 $form->post_content = $post_content; 53 $form->post_excerpt_xhtml = $post_excerpt_xhtml; 54 $form->post_content_xhtml = $post_content_xhtml; 55 56 $cur = $core->con->openCursor($core->prefix.'post'); 57 58 $cur->post_title = $form->post_title; 59 $cur->cat_id = $form->cat_id ? $form->cat_id : null; 60 $cur->post_dt = $form->post_dt ? date('Y-m-d H:i:00',strtotime($form->post_dt)) : ''; 61 $cur->post_format = $form->post_format; 62 $cur->post_password = $form->post_password; 63 $cur->post_lang = $form->post_lang; 64 $cur->post_title = $form->post_title; 65 $cur->post_excerpt = $form->post_excerpt; 66 $cur->post_excerpt_xhtml = $form->post_excerpt_xhtml; 67 $cur->post_content = $form->post_content; 68 $cur->post_content_xhtml = $form->post_content_xhtml; 69 $cur->post_notes = $form->post_notes; 70 $cur->post_status = $form->post_status; 71 $cur->post_selected = (integer) $form->post_selected; 72 $cur->post_open_comment = (integer) $form->post_open_comment; 73 $cur->post_open_tb = (integer) $form->post_open_tb; 74 75 if (!empty($form->post_url)) { 76 $cur->post_url = $form->post_url; 77 } 78 79 # Update post 80 if ($form->id) 81 { 82 # --BEHAVIOR-- adminBeforePostUpdate 83 $core->callBehavior('adminBeforePostUpdate',$cur,$form->id); 84 85 $core->blog->updPost($form->id,$cur); 86 87 # --BEHAVIOR-- adminAfterPostUpdate 88 $core->callBehavior('adminAfterPostUpdate',$cur,$form->id); 89 http::redirect('post.php?id='.$form->id.'&upd=1'); 90 } 91 else 92 { 93 $cur->user_id = $core->auth->userID(); 94 # --BEHAVIOR-- adminBeforePostCreate 95 $core->callBehavior('adminBeforePostCreate',$cur); 96 97 $return_id = $core->blog->addPost($cur); 98 99 # --BEHAVIOR-- adminAfterPostCreate 100 $core->callBehavior('adminAfterPostCreate',$cur,$return_id); 101 102 http::redirect('post.php?id='.$return_id.'&crea=1'); 103 } 104 105 } catch (Exception $e) { 106 $_ctx->addError($e->getMessage()); 107 } 108 } 109 public static function deletePost($form) { 110 global $core,$_ctx; 111 if ($form->can_delete) { 112 try { 113 $post_id = $form->id; 114 $core->callBehavior('adminBeforePostDelete',$post_id); 115 $core->blog->delPost($post_id); 116 http::redirect('posts.php'); 117 exit; 118 } catch (Exception $e) { 119 $_ctx->addError($e->getMessage()); 120 } 121 } 122 } 123 } 34 124 35 125 $page_title = __('New entry'); 36 126 $post_id=''; 37 127 $can_view_page = true; 38 128 $can_edit_post = $core->auth->check('usage,contentadmin',$core->blog->id); … … 47 137 # If user can't publish 48 138 if (!$can_publish) { 49 $ post_status = -2;139 $form->post_status = -2; 50 140 } 51 141 52 142 # Getting categories 53 $categories_combo = dcAdminCombos::getCategoriesCombo( 54 $core->blog->getCategories(array('post_type'=>'post')) 55 ); 56 57 $status_combo = dcAdminCombos::getPostStatusesCombo(); 58 59 $img_status_pattern = '<img class="img_select_option" alt="%1$s" title="%1$s" src="images/%2$s" />'; 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 # Status combo 155 foreach ($core->blog->getAllPostStatus() as $k => $v) { 156 $status_combo[$k] = $v; 157 } 60 158 61 159 # Formaters combo 62 $formaters_combo = dcAdminCombos::getFormatersCombo(); 160 foreach ($core->getFormaters() as $v) { 161 $formaters_combo[$v] = $v; 162 } 63 163 64 164 # Languages combo 65 165 $rs = $core->blog->getLangs(array('order'=>'asc')); 66 $lang_combo = dcAdminCombos::getLangsCombo($rs,true); 67 68 # Validation flag 69 $bad_dt = false; 70 71 # Trackbacks 72 $TB = new dcTrackback($core); 73 $tb_urls = $tb_excerpt = ''; 74 166 $all_langs = l10n::getISOcodes(0,1); 167 $lang_combo = array('' => '', __('Most used') => array(), __('Available') => l10n::getISOcodes(0,1)); 168 while ($rs->fetch()) { 169 if (isset($all_langs[$rs->post_lang])) { 170 $lang_combo[__('Most used')][$rs->post_lang] = $all_langs[$rs->post_lang]; 171 unset($lang_combo[__('Available')][$rs->post_lang]); 172 } else { 173 $lang_combo[__('Most used')][$rs->post_lang] = $all_langs[$rs->post_lang]; 174 } 175 } 176 unset($all_langs); 177 unset($rs); 178 179 $form = new dcForm($core,'post','post.php'); 180 $form 181 ->addField( 182 new dcFieldText('post_title','', array( 183 'maxlength' => 255, 184 'required' => true, 185 'label' => __('Title:')))) 186 ->addField( 187 new dcFieldTextArea('post_excerpt','', array( 188 'cols' => 50, 189 'rows' => 5, 190 'label' => __("Excerpt:").'<span class="form-note">'. 191 __('Add an introduction to the post.').'</span>'))) 192 ->addField( 193 new dcFieldTextArea('post_content','', array( 194 'required' => true, 195 'label' => __("Content:")))) 196 ->addField( 197 new dcFieldTextArea('post_notes','', array( 198 'label' => __("Notes")))) 199 ->addField( 200 new dcFieldSubmit('save',__('Save'),array( 201 'action' => array('PostActions','savePost')))) 202 ->addField( 203 new dcFieldSubmit('delete',__('Delete'),array( 204 'action' => array('PostActions','deletePost')))) 205 ->addField( 206 new dcFieldCombo('post_status',$core->auth->getInfo('user_post_status'),$status_combo,array( 207 'disabled' => !$can_publish, 208 'label' => __('Entry status')))) 209 ->addField( 210 new dcFieldCombo('cat_id','',$categories_combo,array( 211 "label" => __('Category')))) 212 ->addField( 213 new dcFieldCombo('new_cat_parent','',$categories_combo,array( 214 "label" => __('Parent:')))) 215 ->addField( 216 new dcFieldText('new_cat_title','', array( 217 'maxlength' => 255, 218 'label' => __('Title')))) 219 220 ->addField( 221 new dcFieldText('post_dt','',array( 222 "label" => __('Publication date and hour')))) 223 ->addField( 224 new dcFieldCombo('post_format',$core->auth->getOption('post_format'),$formaters_combo,array( 225 "label" => __('Text formating')))) 226 ->addField( 227 new dcFieldCheckbox ('post_open_comment',$core->blog->settings->system->allow_comments,array( 228 "label" => __('Accept comments')))) 229 ->addField( 230 new dcFieldCheckbox ('post_open_tb',$core->blog->settings->system->allow_trackbacks,array( 231 "label" => __('Accept trackbacks')))) 232 ->addField( 233 new dcFieldCheckbox ('post_selected',array(1=>false),array( 234 "label" => __('Selected entry')))) 235 ->addField( 236 new dcFieldCombo ('post_lang',$core->auth->getInfo('user_lang'),$lang_combo, array( 237 "label" => __('Entry lang:')))) 238 ->addField( 239 new dcFieldText('post_password','',array( 240 "maxlength" => 32, 241 "label" => __('Entry password:')))) 242 ->addField( 243 new dcFieldText('post_url','',array( 244 "maxlength" => 255, 245 "label" => __('Basename:')))) 246 ->addField( 247 new dcFieldHidden ('id','')) 248 ; 75 249 # Get entry informations 76 250 if (!empty($_REQUEST['id'])) 77 251 { 78 $page_title = __('Edit entry');79 80 252 $params['post_id'] = $_REQUEST['id']; 81 253 82 254 $post = $core->blog->getPosts($params); 83 255 84 256 if ($post->isEmpty()) 85 257 { … … 89 261 else 90 262 { 91 $post_id = $post->post_id; 92 $cat_id = $post->cat_id; 93 $post_dt = date('Y-m-d H:i',strtotime($post->post_dt)); 94 $post_format = $post->post_format; 95 $post_password = $post->post_password; 96 $post_url = $post->post_url; 97 $post_lang = $post->post_lang; 98 $post_title = $post->post_title; 99 $post_excerpt = $post->post_excerpt; 100 $post_excerpt_xhtml = $post->post_excerpt_xhtml; 101 $post_content = $post->post_content; 102 $post_content_xhtml = $post->post_content_xhtml; 103 $post_notes = $post->post_notes; 104 $post_status = $post->post_status; 105 $post_selected = (boolean) $post->post_selected; 106 $post_open_comment = (boolean) $post->post_open_comment; 107 $post_open_tb = (boolean) $post->post_open_tb; 108 109 $can_edit_post = $post->isEditable(); 110 $can_delete= $post->isDeletable(); 111 263 $form->id = $post_id = $post->post_id; 264 $form->cat_id = $post->cat_id; 265 $form->post_dt = date('Y-m-d H:i',strtotime($post->post_dt)); 266 $form->post_format = $post->post_format; 267 $form->post_password = $post->post_password; 268 $form->post_url = $post->post_url; 269 $form->post_lang = $post->post_lang; 270 $form->post_title = $post->post_title; 271 $form->post_excerpt = $post->post_excerpt; 272 $form->post_excerpt_xhtml = $post->post_excerpt_xhtml; 273 $form->post_content = $post->post_content; 274 $form->post_content_xhtml = $post->post_content_xhtml; 275 $form->post_notes = $post->post_notes; 276 $form->post_status = $post->post_status; 277 $form->post_selected = (boolean) $post->post_selected; 278 $form->post_open_comment = (boolean) $post->post_open_comment; 279 $form->post_open_tb = (boolean) $post->post_open_tb; 280 $form->can_edit_post = $post->isEditable(); 281 $form->can_delete= $post->isDeletable(); 112 282 $next_rs = $core->blog->getNextPost($post,1); 113 283 $prev_rs = $core->blog->getNextPost($post,-1); 114 284 115 285 if ($next_rs !== null) { 116 $next_link = sprintf($post_link,$next_rs->post_id, 117 html::escapeHTML($next_rs->post_title),__('Next entry').' »'); 118 $next_headlink = sprintf($post_headlink,'next', 119 html::escapeHTML($next_rs->post_title),$next_rs->post_id); 120 } 121 286 $_ctx->next_post = array('id' => $next_rs->post_id,'title' => $next_rs->post_title); 287 } 122 288 if ($prev_rs !== null) { 123 $prev_link = sprintf($post_link,$prev_rs->post_id, 124 html::escapeHTML($prev_rs->post_title),'« '.__('Previous entry')); 125 $prev_headlink = sprintf($post_headlink,'previous', 126 html::escapeHTML($prev_rs->post_title),$prev_rs->post_id); 127 } 128 129 try { 130 $core->media = new dcMedia($core); 131 } catch (Exception $e) { 132 $core->error->add($e->getMessage()); 133 } 134 135 # Sanitize trackbacks excerpt 136 $tb_excerpt = empty($_POST['tb_excerpt']) ? 137 $post_excerpt_xhtml.' '.$post_content_xhtml : 138 $_POST['tb_excerpt']; 139 $tb_excerpt = html::decodeEntities(html::clean($tb_excerpt)); 140 $tb_excerpt = text::cutString(html::escapeHTML($tb_excerpt), 255); 141 $tb_excerpt = preg_replace('/\s+/ms', ' ', $tb_excerpt); 142 } 143 } 144 if (isset($_REQUEST['section']) && $_REQUEST['section']=='trackbacks') { 145 $anchor = 'trackbacks'; 146 } else { 147 $anchor = 'comments'; 148 } 149 150 $comments_actions_page = new dcCommentsActionsPage($core,'post.php',array('id' => $post_id, '_ANCHOR'=>$anchor,'section' => $anchor)); 151 152 if ($comments_actions_page->process()) { 153 return; 154 } 155 156 # Ping blogs 157 if (!empty($_POST['ping'])) 158 { 159 if (!empty($_POST['tb_urls']) && $post_id && $post_status == 1 && $can_edit_post) 160 { 161 $tb_urls = $_POST['tb_urls']; 162 $tb_urls = str_replace("\r", '', $tb_urls); 163 $tb_post_title = html::escapeHTML(trim(html::clean($post_title))); 164 $tb_post_url = $post->getURL(); 165 166 foreach (explode("\n", $tb_urls) as $tb_url) 167 { 168 try { 169 $TB->ping($tb_url, $post_id, $tb_post_title, $tb_excerpt, $tb_post_url); 170 } catch (Exception $e) { 171 $core->error->add($e->getMessage()); 172 } 173 } 174 175 if (!$core->error->flag()) { 176 dcPage::addSuccessNotice(__('All pings sent.')); 177 http::redirect('post.php?id='.$post_id.'&tb=1'); 178 } 179 } 180 } 181 182 # Format excerpt and content 183 elseif (!empty($_POST) && $can_edit_post) 184 { 185 $post_format = $_POST['post_format']; 186 $post_excerpt = $_POST['post_excerpt']; 187 $post_content = $_POST['post_content']; 188 189 $post_title = $_POST['post_title']; 190 191 $cat_id = (integer) $_POST['cat_id']; 192 193 if (isset($_POST['post_status'])) { 194 $post_status = (integer) $_POST['post_status']; 195 } 196 197 if (empty($_POST['post_dt'])) { 198 $post_dt = ''; 199 } else { 200 try 201 { 202 $post_dt = strtotime($_POST['post_dt']); 203 if ($post_dt == false || $post_dt == -1) { 204 $bad_dt = true; 205 throw new Exception(__('Invalid publication date')); 206 } 207 $post_dt = date('Y-m-d H:i',$post_dt); 208 } 209 catch (Exception $e) 210 { 211 $core->error->add($e->getMessage()); 212 } 213 } 214 215 $post_open_comment = !empty($_POST['post_open_comment']); 216 $post_open_tb = !empty($_POST['post_open_tb']); 217 $post_selected = !empty($_POST['post_selected']); 218 $post_lang = $_POST['post_lang']; 219 $post_password = !empty($_POST['post_password']) ? $_POST['post_password'] : null; 220 221 $post_notes = $_POST['post_notes']; 222 223 if (isset($_POST['post_url'])) { 224 $post_url = $_POST['post_url']; 225 } 226 227 $core->blog->setPostContent( 228 $post_id,$post_format,$post_lang, 229 $post_excerpt,$post_excerpt_xhtml,$post_content,$post_content_xhtml 230 ); 231 } 232 233 # Delete post 234 if (!empty($_POST['delete']) && $can_delete) 235 { 236 try { 237 # --BEHAVIOR-- adminBeforePostDelete 238 $core->callBehavior('adminBeforePostDelete',$post_id); 239 $core->blog->delPost($post_id); 240 http::redirect('posts.php'); 241 } catch (Exception $e) { 242 $core->error->add($e->getMessage()); 243 } 244 } 245 246 # Create or update post 247 if (!empty($_POST) && !empty($_POST['save']) && $can_edit_post && !$bad_dt) 248 { 249 # Create category 250 if (!empty($_POST['new_cat_title']) && $core->auth->check('categories', $core->blog->id)) { 251 252 $cur_cat = $core->con->openCursor($core->prefix.'category'); 253 $cur_cat->cat_title = $_POST['new_cat_title']; 254 $cur_cat->cat_url = ''; 255 256 $parent_cat = !empty($_POST['new_cat_parent']) ? $_POST['new_cat_parent'] : ''; 257 258 # --BEHAVIOR-- adminBeforeCategoryCreate 259 $core->callBehavior('adminBeforeCategoryCreate', $cur_cat); 260 261 $cat_id = $core->blog->addCategory($cur_cat, (integer) $parent_cat); 262 263 # --BEHAVIOR-- adminAfterCategoryCreate 264 $core->callBehavior('adminAfterCategoryCreate', $cur_cat, $cat_id); 265 } 266 267 $cur = $core->con->openCursor($core->prefix.'post'); 268 269 $cur->post_title = $post_title; 270 $cur->cat_id = ($cat_id ? $cat_id : null); 271 $cur->post_dt = $post_dt ? date('Y-m-d H:i:00',strtotime($post_dt)) : ''; 272 $cur->post_format = $post_format; 273 $cur->post_password = $post_password; 274 $cur->post_lang = $post_lang; 275 $cur->post_title = $post_title; 276 $cur->post_excerpt = $post_excerpt; 277 $cur->post_excerpt_xhtml = $post_excerpt_xhtml; 278 $cur->post_content = $post_content; 279 $cur->post_content_xhtml = $post_content_xhtml; 280 $cur->post_notes = $post_notes; 281 $cur->post_status = $post_status; 282 $cur->post_selected = (integer) $post_selected; 283 $cur->post_open_comment = (integer) $post_open_comment; 284 $cur->post_open_tb = (integer) $post_open_tb; 285 286 if (isset($_POST['post_url'])) { 287 $cur->post_url = $post_url; 288 } 289 290 # Update post 291 if ($post_id) 292 { 293 try 294 { 295 # --BEHAVIOR-- adminBeforePostUpdate 296 $core->callBehavior('adminBeforePostUpdate',$cur,$post_id); 297 298 $core->blog->updPost($post_id,$cur); 299 300 # --BEHAVIOR-- adminAfterPostUpdate 301 $core->callBehavior('adminAfterPostUpdate',$cur,$post_id); 302 dcPage::addSuccessNotice (sprintf(__('The post "%s" has been successfully updated'),html::escapeHTML($cur->post_title))); 303 http::redirect('post.php?id='.$post_id); 304 } 305 catch (Exception $e) 306 { 307 $core->error->add($e->getMessage()); 308 } 309 } 310 else 311 { 312 $cur->user_id = $core->auth->userID(); 313 314 try 315 { 316 # --BEHAVIOR-- adminBeforePostCreate 317 $core->callBehavior('adminBeforePostCreate',$cur); 318 319 $return_id = $core->blog->addPost($cur); 320 321 # --BEHAVIOR-- adminAfterPostCreate 322 $core->callBehavior('adminAfterPostCreate',$cur,$return_id); 323 324 dcPage::addSuccessNotice(__('Entry has been successfully created.')); 325 http::redirect('post.php?id='.$return_id); 326 } 327 catch (Exception $e) 328 { 329 $core->error->add($e->getMessage()); 330 } 331 } 332 } 333 334 # Getting categories 335 $categories_combo = dcAdminCombos::getCategoriesCombo( 336 $core->blog->getCategories(array('post_type'=>'post')) 337 ); 289 $_ctx->prev_post = array('id' => $prev_rs->post_id,'title' => $prev_rs->post_title); 290 } 291 $page_title = __('Edit entry'); 292 293 } 294 } 295 if ($post_id) { 296 $_ctx->post_id = $post->post_id; 297 298 $_ctx->preview_url = 299 $core->blog->url.$core->url->getURLFor('preview',$core->auth->userID().'/'. 300 http::browserUID(DC_MASTER_KEY.$core->auth->userID().$core->auth->getInfo('user_pwd')). 301 '/'.$post->post_url); 302 303 304 $form_comment = new dcForm($core,'add-comment','comment.php'); 305 $form_comment 306 ->addField( 307 new dcFieldText('comment_author','', array( 308 'maxlength' => 255, 309 'required' => true, 310 'label' => __('Name:')))) 311 ->addField( 312 new dcFieldText('comment_email','', array( 313 'maxlength' => 255, 314 'required' => true, 315 'label' => __('Email:')))) 316 ->addField( 317 new dcFieldText('comment_site','', array( 318 'maxlength' => 255, 319 'label' => __('Web site:')))) 320 ->addField( 321 new dcFieldTextArea('comment_content','', array( 322 'required' => true, 323 'label' => __('Comment:')))) 324 ->addField( 325 new dcFieldHidden('post_id',$post_id)) 326 ->addField( 327 new dcFieldSubmit('add',__('Save'),array( 328 'action' => 'addComment'))) 329 ; 330 331 332 } 333 334 $form->setup(); 335 336 $sidebar_blocks = new ArrayObject(array( 337 'status-box' => array( 338 'title' => __('Status'), 339 'items' => array('post_status','post_dt','post_lang','post_format')), 340 'metas-box' => array( 341 'title' => __('Ordering'), 342 'items' => array('post_selected','cat_id')), 343 'options-box' => array( 344 'title' => __('Options'), 345 'items' => array('post_open_comment','post_open_tb','post_password','post_url')) 346 )); 347 348 $main_blocks = new ArrayObject(array( 349 "post_title","post_excerpt","post_content","post_notes" 350 )); 351 352 353 $_ctx->sidebar_blocks = $sidebar_blocks; 354 $_ctx->main_blocks = $main_blocks; 355 338 356 /* DISPLAY 339 357 -------------------------------------------------------- */ … … 345 363 $default_tab = 'comments'; 346 364 } 347 elseif (!empty($_GET['tb'])) { 348 $default_tab = 'trackbacks'; 349 } 350 351 if ($post_id) { 352 switch ($post_status) { 353 case 1: 354 $img_status = sprintf($img_status_pattern,__('Published'),'check-on.png'); 355 break; 356 case 0: 357 $img_status = sprintf($img_status_pattern,__('Unpublished'),'check-off.png'); 358 break; 359 case -1: 360 $img_status = sprintf($img_status_pattern,__('Scheduled'),'scheduled.png'); 361 break; 362 case -2: 363 $img_status = sprintf($img_status_pattern,__('Pending'),'check-wrn.png'); 364 break; 365 default: 366 $img_status = ''; 367 } 368 $edit_entry_str = __('“%s”'); 369 $page_title_edit = sprintf($edit_entry_str, html::escapeHTML($post_title)).' '.$img_status; 370 } else { 371 $img_status = ''; 372 } 373 374 375 dcPage::open($page_title.' - '.__('Entries'), 376 dcPage::jsDatePicker(). 377 dcPage::jsToolBar(). 378 dcPage::jsModal(). 379 dcPage::jsMetaEditor(). 380 dcPage::jsLoad('js/_post.js'). 381 dcPage::jsConfirmClose('entry-form','comment-form'). 382 # --BEHAVIOR-- adminPostHeaders 383 $core->callBehavior('adminPostHeaders'). 384 dcPage::jsPageTabs($default_tab). 385 $next_headlink."\n".$prev_headlink, 386 dcPage::breadcrumb( 365 $page_title_edit = __('Edit entry'); 366 $_ctx 367 ->setBreadCrumb( 387 368 array( 388 369 html::escapeHTML($core->blog->name) => '', 389 370 __('Entries') => 'posts.php', 390 371 ($post_id ? $page_title_edit : $page_title) => '' 391 )) 392 ); 372 )) 373 ->default_tab = $default_tab; 374 $_ctx->post_status = $form->post_status; 375 $_ctx->post_title = $form->post_title; 376 if ($form->post_status == 1) { 377 $_ctx->post_url = $post->getURL(); 378 } 393 379 394 380 if (!empty($_GET['upd'])) { 395 dcPage::success(__('Entry has been successfully updated.'));381 $_ctx->setAlert(__('Entry has been successfully updated.')); 396 382 } 397 383 elseif (!empty($_GET['crea'])) { 398 dcPage::success(__('Entry has been successfully created.'));384 $_ctx->setAlert(__('Entry has been successfully created.')); 399 385 } 400 386 elseif (!empty($_GET['attached'])) { 401 dcPage::success(__('File has been successfully attached.'));387 $_ctx->setAlert(__('File has been successfully attached.')); 402 388 } 403 389 elseif (!empty($_GET['rmattach'])) { 404 dcPage::success(__('Attachment has been successfully removed.')); 405 } 406 390 $_ctx->setAlert(__('Attachment has been successfully removed.')); 391 } 407 392 if (!empty($_GET['creaco'])) { 408 dcPage::success(__('Comment has been successfully created.')); 409 } 410 if (!empty($_GET['tbsent'])) { 411 dcPage::success(__('All pings sent.')); 412 } 413 414 # XHTML conversion 415 if (!empty($_GET['xconv'])) 416 { 417 $post_excerpt = $post_excerpt_xhtml; 418 $post_content = $post_content_xhtml; 419 $post_format = 'xhtml'; 420 421 dcPage::message(__('Don\'t forget to validate your XHTML conversion by saving your post.')); 422 } 423 424 if ($post_id && $post->post_status == 1) { 425 echo '<p><a class="onblog_link outgoing" href="'.$post->getURL().'" title="'.$post_title.'">'.__('Go to this entry on the site').' <img src="images/outgoing-blue.png" alt="" /></a></p>'; 426 } 427 if ($post_id) 428 { 429 echo '<p class="nav_prevnext">'; 430 if ($prev_link) { echo $prev_link; } 431 if ($next_link && $prev_link) { echo ' | '; } 432 if ($next_link) { echo $next_link; } 433 434 # --BEHAVIOR-- adminPostNavLinks 435 $core->callBehavior('adminPostNavLinks',isset($post) ? $post : null); 436 437 echo '</p>'; 438 } 439 440 # Exit if we cannot view page 441 if (!$can_view_page) { 442 dcPage::helpBlock('core_post'); 443 dcPage::close(); 444 exit; 445 } 446 /* Post form if we can edit post 447 -------------------------------------------------------- */ 448 if ($can_edit_post) 449 { 450 $sidebar_items = new ArrayObject(array( 451 'status-box' => array( 452 'title' => __('Status'), 453 'items' => array( 454 'post_status' => 455 '<p class="entry-status"><label for="post_status">'.__('Entry status').' '.$img_status.'</label>'. 456 form::combo('post_status',$status_combo,$post_status,'maximal','',!$can_publish). 457 '</p>', 458 'post_dt' => 459 '<p><label for="post_dt">'.__('Publication date and hour').'</label>'. 460 form::field('post_dt',16,16,$post_dt,($bad_dt ? 'invalid' : '')). 461 '</p>', 462 'post_lang' => 463 '<p><label for="post_lang">'.__('Entry language').'</label>'. 464 form::combo('post_lang',$lang_combo,$post_lang). 465 '</p>', 466 'post_format' => 467 '<div>'. 468 '<h5 id="label_format"><label for="post_format" class="classic">'.__('Text formatting').'</label></h5>'. 469 '<p>'.form::combo('post_format',$formaters_combo,$post_format,'maximal'). 470 '</p>'. 471 '<p class="format_control control_no_xhtml">'. 472 '<a id="convert-xhtml" class="button'.($post_id && $post_format != 'wiki' ? ' hide' : '').'" href="post.php?id='.$post_id.'&xconv=1">'. 473 __('Convert to XHTML').'</a></p></div>')), 474 'metas-box' => array( 475 'title' => __('Filing'), 476 'items' => array( 477 'post_selected' => 478 '<p><label for="post_selected" class="classic">'. 479 form::checkbox('post_selected',1,$post_selected).' '. 480 __('Selected entry').'</label></p>', 481 'cat_id' => 482 '<div>'. 483 '<h5 id="label_cat_id">'.__('Category').'</h5>'. 484 '<p><label for="cat_id">'.__('Category:').'</label>'. 485 form::combo('cat_id',$categories_combo,$cat_id,'maximal'). 486 '</p>'. 487 ($core->auth->check('categories', $core->blog->id) ? 488 '<div>'. 489 '<h5 id="create_cat">'.__('Add a new category').'</h5>'. 490 '<p><label for="new_cat_title">'.__('Title:').' '. 491 form::field('new_cat_title',30,255,'','maximal').'</label></p>'. 492 '<p><label for="new_cat_parent">'.__('Parent:').' '. 493 form::combo('new_cat_parent',$categories_combo,'','maximal'). 494 '</label></p>'. 495 '</div>' 496 : ''). 497 '</div>')), 498 'options-box' => array( 499 'title' => __('Options'), 500 'items' => array( 501 'post_open_comment_tb' => 502 '<div>'. 503 '<h5 id="label_comment_tb">'.__('Comments and trackbacks list').'</h5>'. 504 '<p><label for="post_open_comment" class="classic">'. 505 form::checkbox('post_open_comment',1,$post_open_comment).' '. 506 __('Accept comments').'</label></p>'. 507 ($core->blog->settings->system->allow_comments ? 508 (isContributionAllowed($post_id,strtotime($post_dt),true) ? 509 '' : 510 '<p class="form-note warn">'. 511 __('Warning: Comments are not more accepted for this entry.').'</p>') : 512 '<p class="form-note warn">'. 513 __('Comments are not accepted on this blog so far.').'</p>'). 514 '<p><label for="post_open_tb" class="classic">'. 515 form::checkbox('post_open_tb',1,$post_open_tb).' '. 516 __('Accept trackbacks').'</label></p>'. 517 ($core->blog->settings->system->allow_trackbacks ? 518 (isContributionAllowed($post_id,strtotime($post_dt),false) ? 519 '' : 520 '<p class="form-note warn">'. 521 __('Warning: Trackbacks are not more accepted for this entry.').'</p>') : 522 '<p class="form-note warn">'.__('Trackbacks are not accepted on this blog so far.').'</p>'). 523 '</div>', 524 'post_password' => 525 '<p><label for="post_password">'.__('Password').'</label>'. 526 form::field('post_password',10,32,html::escapeHTML($post_password),'maximal'). 527 '</p>', 528 'post_url' => 529 '<div class="lockable">'. 530 '<p><label for="post_url">'.__('Edit basename').'</label>'. 531 form::field('post_url',10,255,html::escapeHTML($post_url),'maximal'). 532 '</p>'. 533 '<p class="form-note warn">'. 534 __('Warning: If you set the URL manually, it may conflict with another entry.'). 535 '</p></div>' 536 )))); 537 538 $main_items = new ArrayObject(array( 539 "post_title" => 540 '<p class="col">'. 541 '<label class="required no-margin bold"><abbr title="'.__('Required field').'">*</abbr> '.__('Title:').'</label>'. 542 form::field('post_title',20,255,html::escapeHTML($post_title),'maximal'). 543 '</p>', 544 545 "post_excerpt" => 546 '<p class="area" id="excerpt-area"><label for="post_excerpt" class="bold">'.__('Excerpt:').' <span class="form-note">'. 547 __('Introduction to the post.').'</span></label> '. 548 form::textarea('post_excerpt',50,5,html::escapeHTML($post_excerpt)). 549 '</p>', 550 551 "post_content" => 552 '<p class="area" id="content-area"><label class="required bold" '. 553 'for="post_content"><abbr title="'.__('Required field').'">*</abbr> '.__('Content:').'</label> '. 554 form::textarea('post_content',50,$core->auth->getOption('edit_size'),html::escapeHTML($post_content)). 555 '</p>', 556 557 "post_notes" => 558 '<p class="area" id="notes-area"><label for="post_notes" class="bold">'.__('Personal notes:').' <span class="form-note">'. 559 __('Unpublished notes.').'</span></label>'. 560 form::textarea('post_notes',50,5,html::escapeHTML($post_notes)). 561 '</p>' 562 ) 563 ); 564 565 # --BEHAVIOR-- adminPostFormItems 566 $core->callBehavior('adminPostFormItems',$main_items,$sidebar_items, isset($post) ? $post : null); 567 568 echo '<div class="multi-part" title="'.($post_id ? __('Edit entry') : __('New entry')).'" id="edit-entry">'; 569 echo '<form action="post.php" method="post" id="entry-form">'; 570 echo '<div id="entry-wrapper">'; 571 echo '<div id="entry-content"><div class="constrained">'; 572 573 echo '<h3 class="out-of-screen-if-js">'.__('Edit post').'</h3>'; 574 575 foreach ($main_items as $id => $item) { 576 echo $item; 577 } 578 579 # --BEHAVIOR-- adminPostForm (may be deprecated) 580 $core->callBehavior('adminPostForm',isset($post) ? $post : null); 581 582 echo 583 '<p class="border-top">'. 584 ($post_id ? form::hidden('id',$post_id) : ''). 585 '<input type="submit" value="'.__('Save').' (s)" '. 586 'accesskey="s" name="save" /> '; 587 if ($post_id) { 588 $preview_url = 589 $core->blog->url.$core->url->getURLFor('preview',$core->auth->userID().'/'. 590 http::browserUID(DC_MASTER_KEY.$core->auth->userID().$core->auth->getInfo('user_pwd')). 591 '/'.$post->post_url); 592 echo '<a id="post-preview" href="'.$preview_url.'" class="button modal" accesskey="p">'.__('Preview').' (p)'.'</a> '; 593 } else { 594 echo 595 '<a id="post-cancel" href="index.php" class="button" accesskey="c">'.__('Cancel').' (c)</a>'; 596 } 597 598 echo 599 ($can_delete ? '<input type="submit" class="delete" value="'.__('Delete').'" name="delete" />' : ''). 600 $core->formNonce(). 601 '</p>'; 602 603 echo '</div></div>'; // End #entry-content 604 echo '</div>'; // End #entry-wrapper 605 606 echo '<div id="entry-sidebar">'; 607 608 foreach ($sidebar_items as $id => $c) { 609 echo '<div id="'.$id.'" class="sb-box">'. 610 '<h4>'.$c['title'].'</h4>'; 611 foreach ($c['items'] as $e_name=>$e_content) { 612 echo $e_content; 613 } 614 echo '</div>'; 615 } 616 617 618 # --BEHAVIOR-- adminPostFormSidebar (may be deprecated) 619 $core->callBehavior('adminPostFormSidebar',isset($post) ? $post : null); 620 echo '</div>'; // End #entry-sidebar 621 622 echo '</form>'; 623 624 # --BEHAVIOR-- adminPostForm 625 $core->callBehavior('adminPostAfterForm',isset($post) ? $post : null); 626 627 echo '</div>'; 628 } 629 630 if ($post_id) 631 { 632 /* Comments 633 -------------------------------------------------------- */ 634 635 $params = array('post_id' => $post_id, 'order' => 'comment_dt ASC'); 636 637 $comments = $core->blog->getComments(array_merge($params,array('comment_trackback'=>0))); 638 639 echo 640 '<div id="comments" class="clear multi-part" title="'.__('Comments').'">'; 641 $combo_action = $comments_actions_page->getCombo(); 642 $has_action = !empty($combo_action) && !$comments->isEmpty(); 643 echo 644 '<p class="top-add"><a class="button add" href="#comment-form">'.__('Add a comment').'</a></p>'; 645 646 if ($has_action) { 647 echo '<form action="post.php" id="form-comments" method="post">'; 648 } 649 650 echo '<h3>'.__('Comments').'</h3>'; 651 if (!$comments->isEmpty()) { 652 showComments($comments,$has_action); 653 } else { 654 echo '<p>'.__('No comment').'</p>'; 655 } 656 657 if ($has_action) { 658 echo 659 '<div class="two-cols">'. 660 '<p class="col checkboxes-helpers"></p>'. 661 662 '<p class="col right"><label for="action" class="classic">'.__('Selected comments action:').'</label> '. 663 form::combo('action',$combo_action). 664 form::hidden(array('section'),'comments'). 665 form::hidden(array('id'),$post_id). 666 $core->formNonce(). 667 '<input type="submit" value="'.__('ok').'" /></p>'. 668 '</div>'. 669 '</form>'; 670 } 671 /* Add a comment 672 -------------------------------------------------------- */ 673 674 echo 675 '<div class="fieldset clear">'. 676 '<h3>'.__('Add a comment').'</h3>'. 677 678 '<form action="comment.php" method="post" id="comment-form">'. 679 '<div class="constrained">'. 680 '<p><label for="comment_author" class="required"><abbr title="'.__('Required field').'">*</abbr> '.__('Name:').'</label>'. 681 form::field('comment_author',30,255,html::escapeHTML($core->auth->getInfo('user_cn'))). 682 '</p>'. 683 684 '<p><label for="comment_email">'.__('Email:').'</label>'. 685 form::field('comment_email',30,255,html::escapeHTML($core->auth->getInfo('user_email'))). 686 '</p>'. 687 688 '<p><label for="comment_site">'.__('Web site:').'</label>'. 689 form::field('comment_site',30,255,html::escapeHTML($core->auth->getInfo('user_url'))). 690 '</p>'. 691 692 '<p class="area"><label for="comment_content" class="required"><abbr title="'.__('Required field').'">*</abbr> '. 693 __('Comment:').'</label> '. 694 form::textarea('comment_content',50,8,html::escapeHTML('')). 695 '</p>'. 696 697 '<p>'. 698 form::hidden('post_id',$post_id). 699 $core->formNonce(). 700 '<input type="submit" name="add" value="'.__('Save').'" /></p>'. 701 '</div>'. #constrained 702 703 '</form>'. 704 '</div>'. #add comment 705 '</div>'; #comments 706 } 707 708 if ($post_id && $post_status == 1) 709 { 710 /* Trackbacks 711 -------------------------------------------------------- */ 712 713 $params = array('post_id' => $post_id, 'order' => 'comment_dt ASC'); 714 $trackbacks = $core->blog->getComments(array_merge($params, array('comment_trackback' => 1))); 715 716 # Actions combo box 717 $combo_action = $comments_actions_page->getCombo(); 718 $has_action = !empty($combo_action) && !$trackbacks->isEmpty(); 719 720 if (!empty($_GET['tb_auto'])) { 721 $tb_urls = implode("\n", $TB->discover($post_excerpt_xhtml.' '.$post_content_xhtml)); 722 } 723 724 # Display tab 725 echo 726 '<div id="trackbacks" class="clear multi-part" title="'.__('Trackbacks').'">'; 727 728 # tracbacks actions 729 if ($has_action) { 730 echo '<form action="post.php" id="form-trackbacks" method="post">'; 731 } 732 733 echo '<h3>'.__('Trackbacks received').'</h3>'; 734 735 if (!$trackbacks->isEmpty()) { 736 showComments($trackbacks, $has_action, true); 737 } else { 738 echo '<p>'.__('No trackback').'</p>'; 739 } 740 741 if ($has_action) { 742 echo 743 '<div class="two-cols">'. 744 '<p class="col checkboxes-helpers"></p>'. 745 746 '<p class="col right"><label for="action" class="classic">'.__('Selected trackbacks action:').'</label> '. 747 form::combo('action', $combo_action). 748 form::hidden('id',$post_id). 749 form::hidden(array('section'),'trackbacks'). 750 $core->formNonce(). 751 '<input type="submit" value="'.__('ok').'" /></p>'. 752 '</div>'. 753 '</form>'; 754 } 755 756 /* Add trackbacks 757 -------------------------------------------------------- */ 758 if ($can_edit_post && $post->post_status) { 759 echo 760 '<div class="fieldset clear">'; 761 762 echo 763 '<h3>'.__('Ping blogs').'</h3>'. 764 '<form action="post.php?id='.$post_id.'" id="trackback-form" method="post">'. 765 '<p><label for="tb_urls" class="area">'.__('URLs to ping:').'</label>'. 766 form::textarea('tb_urls', 60, 5, $tb_urls). 767 '</p>'. 768 769 '<p><label for="tb_excerpt" class="area">'.__('Excerpt to send:').'</label>'. 770 form::textarea('tb_excerpt', 60, 5, $tb_excerpt).'</p>'. 771 772 '<p>'. 773 $core->formNonce(). 774 '<input type="submit" name="ping" value="'.__('Ping blogs').'" />'. 775 (empty($_GET['tb_auto']) ? 776 ' <a class="button" href="'. 777 'post.php?id='.$post_id.'&tb_auto=1&tb=1'. 778 '">'.__('Auto discover ping URLs').'</a>' 779 : ''). 780 '</p>'. 781 '</form>'; 782 783 $pings = $TB->getPostPings($post_id); 784 785 if (!$pings->isEmpty()) 786 { 787 echo '<h3>'.__('Previously sent pings').'</h3>'; 788 789 echo '<ul class="nice">'; 790 while ($pings->fetch()) { 791 echo 792 '<li>'.dt::dt2str(__('%Y-%m-%d %H:%M'), $pings->ping_dt).' - '. 793 $pings->ping_url.'</li>'; 794 } 795 echo '</ul>'; 796 } 797 798 echo '</div>'; 799 } 800 801 echo '</div>'; #trackbacks 802 } 803 804 # Controls comments or trakbacks capabilities 805 function isContributionAllowed($id,$dt,$com=true) 806 { 807 global $core; 808 809 if (!$id) { 810 return true; 811 } 812 if ($com) { 813 if (($core->blog->settings->system->comments_ttl == 0) || 814 (time() - $core->blog->settings->system->comments_ttl*86400 < $dt)) { 815 return true; 816 } 817 } else { 818 if (($core->blog->settings->system->trackbacks_ttl == 0) || 819 (time() - $core->blog->settings->system->trackbacks_ttl*86400 < $dt)) { 820 return true; 821 } 822 } 823 return false; 824 } 825 826 # Show comments or trackbacks 827 function showComments($rs,$has_action,$tb=false) 828 { 829 echo 830 '<div class="table-outer">'. 831 '<table class="comments-list"><tr>'. 832 '<th colspan="2" class="first">'.__('Author').'</th>'. 833 '<th>'.__('Date').'</th>'. 834 '<th class="nowrap">'.__('IP address').'</th>'. 835 '<th>'.__('Status').'</th>'. 836 '<th>'.__('Edit').'</th>'. 837 '</tr>'; 838 $comments = array(); 839 if (isset($_REQUEST['comments'])) { 840 foreach ($_REQUEST['comments'] as $v) { 841 $comments[(integer)$v]=true; 842 } 843 } 844 845 while($rs->fetch()) 846 { 847 $comment_url = 'comment.php?id='.$rs->comment_id; 848 849 $img = '<img alt="%1$s" title="%1$s" src="images/%2$s" />'; 850 switch ($rs->comment_status) { 851 case 1: 852 $img_status = sprintf($img,__('Published'),'check-on.png'); 853 break; 854 case 0: 855 $img_status = sprintf($img,__('Unpublished'),'check-off.png'); 856 break; 857 case -1: 858 $img_status = sprintf($img,__('Pending'),'check-wrn.png'); 859 break; 860 case -2: 861 $img_status = sprintf($img,__('Junk'),'junk.png'); 862 break; 863 } 864 865 echo 866 '<tr class="line'.($rs->comment_status != 1 ? ' offline' : '').'"'. 867 ' id="c'.$rs->comment_id.'">'. 868 869 '<td class="nowrap">'. 870 ($has_action ? form::checkbox(array('comments[]'),$rs->comment_id,isset($comments[$rs->comment_id]),'','',0,'title="'.($tb ? __('select this trackback') : __('select this comment')).'"') : '').'</td>'. 871 '<td class="maximal">'.html::escapeHTML($rs->comment_author).'</td>'. 872 '<td class="nowrap">'.dt::dt2str(__('%Y-%m-%d %H:%M'),$rs->comment_dt).'</td>'. 873 '<td class="nowrap"><a href="comments.php?ip='.$rs->comment_ip.'">'.$rs->comment_ip.'</a></td>'. 874 '<td class="nowrap status">'.$img_status.'</td>'. 875 '<td class="nowrap status"><a href="'.$comment_url.'">'. 876 '<img src="images/edit-mini.png" alt="" title="'.__('Edit this comment').'" /> '.__('Edit').'</a></td>'. 877 878 '</tr>'; 879 } 880 881 echo '</table></div>'; 882 } 883 884 dcPage::helpBlock('core_post','core_trackbacks','core_wiki'); 885 dcPage::close(); 393 $_ctx->setAlert(__('Comment has been successfully created.')); 394 } 395 396 $core->tpl->display('post.html.twig'); 397 ?> -
admin/posts.php
r2566 r2593 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 … … 47 47 { 48 48 # Filter form we'll put in html_block 49 $users_combo = array_merge( 50 array('-' => ''), 51 dcAdminCombos::getUsersCombo($users) 49 $users_combo = $categories_combo = array(); 50 while ($users->fetch()) 51 { 52 $user_cn = dcUtils::getUserCN($users->user_id,$users->user_name, 53 $users->user_firstname,$users->user_displayname); 54 55 if ($user_cn != $users->user_id) { 56 $user_cn .= ' ('.$users->user_id.')'; 57 } 58 59 $users_combo[$user_cn] = $users->user_id; 60 } 61 62 63 # Getting categories 64 $categories_combo = array(); 65 try { 66 $categories = $core->blog->getCategories(array('post_type'=>'post')); 67 while ($categories->fetch()) { 68 $categories_combo[$categories->cat_id] = 69 str_repeat(' ',$categories->level-1). 70 ($categories->level-1 == 0 ? '' : '• '). 71 html::escapeHTML($categories->cat_title); 72 } 73 } catch (Exception $e) { } 74 $status_combo = array( 52 75 ); 76 foreach ($core->blog->getAllPostStatus() as $k => $v) { 77 $status_combo[(string) $k] = (string)$v; 78 } 79 80 $selected_combo = array( 81 '1' => __('is selected'), 82 '0' => __('is not selected') 83 ); 84 85 # Months array 86 while ($dates->fetch()) { 87 $dt_m_combo[$dates->year().$dates->month()] = dt::str('%B %Y',$dates->ts()); 88 } 89 90 while ($langs->fetch()) { 91 $lang_combo[$langs->post_lang] = $langs->post_lang; 92 } 93 } 94 $form = new dcForm($core,'post','post.php'); 53 95 54 $categories_combo = array_merge( 55 array( 56 new formSelectOption('-',''), 57 new formSelectOption(__('(No cat)'),'NULL')), 58 dcAdminCombos::getCategoriesCombo($categories,false) 96 97 # Actions combo box 98 $combo_action = array(); 99 if ($core->auth->check('publish,contentadmin',$core->blog->id)) 100 { 101 $combo_action[__('Status')] = array( 102 __('Publish') => 'publish', 103 __('Unpublish') => 'unpublish', 104 __('Schedule') => 'schedule', 105 __('Mark as pending') => 'pending' 59 106 ); 60 $categories_values = array(); 61 foreach ($categories_combo as $cat) { 62 if (isset($cat->value)) { 63 $categories_values[$cat->value]=true; 64 } 107 } 108 $combo_action[__('Mark')] = array( 109 __('Mark as selected') => 'selected', 110 __('Mark as unselected') => 'unselected' 111 ); 112 $combo_action[__('Change')] = array( 113 __('Change category') => 'category', 114 __('Change language') => 'lang'); 115 if ($core->auth->check('admin',$core->blog->id)) 116 { 117 $combo_action[__('Change')] = array_merge($combo_action[__('Change')], 118 array(__('Change author') => 'author')); 119 } 120 if ($core->auth->check('delete,contentadmin',$core->blog->id)) 121 { 122 $combo_action[__('Delete')] = array(__('Delete') => 'delete'); 123 } 124 125 # --BEHAVIOR-- adminPostsActionsCombo 126 $core->callBehavior('adminPostsActionsCombo',array(&$combo_action)); 127 128 129 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); 135 } 136 } 137 138 class PostsFetcher extends dcListFetcher { 139 140 public function getEntries($params,$offset,$limit) { 141 $params['limit'] = array($offset,$limit); 142 return $this->core->blog->getPosts($params); 65 143 } 66 144 67 $status_combo = array_merge( 68 array('-' => ''), 69 dcAdminCombos::getPostStatusesCombo() 70 ); 71 72 $selected_combo = array( 73 '-' => '', 74 __('Selected') => '1', 75 __('Not selected') => '0' 76 ); 77 78 $attachment_combo = array( 79 '-' => '', 80 __('With attachments') => '1', 81 __('Without attachments') => '0' 82 ); 83 84 # Months array 85 $dt_m_combo = array_merge( 86 array('-' => ''), 87 dcAdminCombos::getDatesCombo($dates) 88 ); 89 90 $lang_combo = array_merge( 91 array('-' => ''), 92 dcAdminCombos::getLangsCombo($langs,false) 93 ); 94 95 $sortby_combo = array( 96 __('Date') => 'post_dt', 97 __('Title') => 'post_title', 98 __('Category') => 'cat_title', 99 __('Author') => 'user_id', 100 __('Status') => 'post_status', 101 __('Selected') => 'post_selected', 102 __('Number of comments') => 'nb_comment', 103 __('Number of trackbacks') => 'nb_trackback' 104 ); 105 106 $order_combo = array( 107 __('Descending') => 'desc', 108 __('Ascending') => 'asc' 109 ); 110 } 111 112 # Actions combo box 113 114 $posts_actions_page = new dcPostsActionsPage($core,'posts.php'); 115 116 if ($posts_actions_page->process()) { 117 return; 118 } 119 120 /* Get posts 121 -------------------------------------------------------- */ 122 $user_id = !empty($_GET['user_id']) ? $_GET['user_id'] : ''; 123 $cat_id = !empty($_GET['cat_id']) ? $_GET['cat_id'] : ''; 124 $status = isset($_GET['status']) ? $_GET['status'] : ''; 125 $selected = isset($_GET['selected']) ? $_GET['selected'] : ''; 126 $attachment = isset($_GET['attachment']) ? $_GET['attachment'] : ''; 127 $month = !empty($_GET['month']) ? $_GET['month'] : ''; 128 $lang = !empty($_GET['lang']) ? $_GET['lang'] : ''; 129 $sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'post_dt'; 130 $order = !empty($_GET['order']) ? $_GET['order'] : 'desc'; 131 132 $show_filters = false; 133 134 $page = !empty($_GET['page']) ? max(1,(integer) $_GET['page']) : 1; 135 $nb_per_page = 30; 136 137 if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) { 138 if ($nb_per_page != $_GET['nb']) { 139 $show_filters = true; 145 public function getEntriesCount($params) { 146 $count = $this->core->blog->getPosts($params,true); 147 return $count->f(0); 140 148 } 141 $nb_per_page = (integer) $_GET['nb'];142 }143 144 $params['limit'] = array((($page-1)*$nb_per_page),$nb_per_page);145 $params['no_content'] = true;146 147 # - User filter148 if ($user_id !== '' && in_array($user_id,$users_combo)) {149 $params['user_id'] = $user_id;150 $show_filters = true;151 } else {152 $user_id='';153 }154 155 # - Categories filter156 if ($cat_id !== '' && isset($categories_values[$cat_id])) {157 $params['cat_id'] = $cat_id;158 $show_filters = true;159 } else {160 $cat_id='';161 }162 163 # - Status filter164 if ($status !== '' && in_array($status,$status_combo)) {165 $params['post_status'] = $status;166 $show_filters = true;167 } else {168 $status='';169 }170 171 # - Selected filter172 if ($selected !== '' && in_array($selected,$selected_combo)) {173 $params['post_selected'] = $selected;174 $show_filters = true;175 } else {176 $selected='';177 }178 179 # - Selected filter180 if ($attachment !== '' && in_array($attachment,$attachment_combo)) {181 $params['media'] = $attachment;182 $params['link_type'] = 'attachment';183 $show_filters = true;184 } else {185 $attachment='';186 }187 188 # - Month filter189 if ($month !== '' && in_array($month,$dt_m_combo)) {190 $params['post_month'] = substr($month,4,2);191 $params['post_year'] = substr($month,0,4);192 $show_filters = true;193 } else {194 $month='';195 }196 197 # - Lang filter198 if ($lang !== '' && in_array($lang,$lang_combo)) {199 $params['post_lang'] = $lang;200 $show_filters = true;201 } else {202 $lang='';203 }204 205 # - Sortby and order filter206 if ($sortby !== '' && in_array($sortby,$sortby_combo)) {207 if ($order !== '' && in_array($order,$order_combo)) {208 $params['order'] = $sortby.' '.$order;209 } else {210 $order='desc';211 }212 213 if ($sortby != 'post_dt' || $order != 'desc') {214 $show_filters = true;215 }216 } else {217 $sortby='post_dt';218 $order='desc';219 }220 221 # Get posts222 try {223 $posts = $core->blog->getPosts($params);224 $counter = $core->blog->getPosts($params,true);225 $post_list = new adminPostList($core,$posts,$counter->f(0));226 } catch (Exception $e) {227 $core->error->add($e->getMessage());228 149 } 229 150 230 151 /* DISPLAY 231 152 -------------------------------------------------------- */ 153 $filterSet = new dcFilterSet($core,'fposts','posts.php'); 232 154 233 $form_filter_title = __('Show filters and display options'); 234 $starting_script = dcPage::jsLoad('js/_posts_list.js'); 235 $starting_script .= dcPage::jsLoad('js/filter-controls.js'); 236 $starting_script .= 237 '<script type="text/javascript">'."\n". 238 "//<![CDATA["."\n". 239 dcPage::jsVar('dotclear.msg.show_filters', $show_filters ? 'true':'false')."\n". 240 dcPage::jsVar('dotclear.msg.filter_posts_list',$form_filter_title)."\n". 241 dcPage::jsVar('dotclear.msg.cancel_the_filter',__('Cancel filters and display options'))."\n". 242 "//]]>". 243 "</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,array( 161 'multiple' => true))) 162 ->addFilter(new dcFilterRichCombo( 163 'post_status',__('Status'), __('Status'), 'post_status', $status_combo)) 164 ->addFilter(new dcFilterRichCombo( 165 'lang',__('Lang'), __('Lang'), 'post_lang', $lang_combo)) 166 ->addFilter(new dcFilterCombo( 167 'selected',__('Selected'), __('The post : '),'post_selected', $selected_combo)) 168 ->addFilter(new monthdcFilterCombo( 169 'month',__('Month'),__('Month'), 'post_month', $dt_m_combo,array('singleval' => 1))) 170 ->addFilter(new dcFilterText( 171 'search',__('Contains'),__('The entry contains'), 'search',20,255)); 244 172 245 dcPage::open(__('Entries'),$starting_script,246 dcPage::breadcrumb(247 array(248 html::escapeHTML($core->blog->name) => '',249 __('Entries') => ''250 ))251 );252 if (!empty($_GET['upd'])) {253 dcPage::success(__('Selected entries have been successfully updated.'));254 } elseif (!empty($_GET['del'])) {255 dcPage::success(__('Selected entries have been successfully deleted.'));256 }257 if (!$core->error->flag())258 {259 echo260 '<p class="top-add"><a class="button add" href="post.php">'.__('New entry').'</a></p>'.261 '<form action="posts.php" method="get" id="filters-form">'.262 '<h3 class="out-of-screen-if-js">'.$form_filter_title.'</h3>'.263 173 264 '<div class="table">'. 265 '<div class="cell">'. 266 '<h4>'.__('Filters').'</h4>'. 267 '<p><label for="user_id" class="ib">'.__('Author:').'</label> '. 268 form::combo('user_id',$users_combo,$user_id).'</p>'. 269 '<p><label for="cat_id" class="ib">'.__('Category:').'</label> '. 270 form::combo('cat_id',$categories_combo,$cat_id).'</p>'. 271 '<p><label for="status" class="ib">'.__('Status:').'</label> ' . 272 form::combo('status',$status_combo,$status).'</p> '. 273 '</div>'. 174 $lfetcher = new PostsFetcher($core); 175 $lposts = new dcItemList ($core,array('lposts','form-entries'),$lfetcher,'posts_actions.php'); 176 $lposts->setFilterSet($filterSet); 177 $lposts->addTemplate('posts_cols.html.twig'); 274 178 275 '<div class="cell filters-sibling-cell">'. 276 '<p><label for="selected" class="ib">'.__('Selected:').'</label> '. 277 form::combo('selected',$selected_combo,$selected).'</p>'. 278 '<p><label for="attachment" class="ib">'.__('Attachments:').'</label> '. 279 form::combo('attachment',$attachment_combo,$attachment).'</p>'. 280 '<p><label for="month" class="ib">'.__('Month:').'</label> '. 281 form::combo('month',$dt_m_combo,$month).'</p>'. 282 '<p><label for="lang" class="ib">'.__('Lang:').'</label> '. 283 form::combo('lang',$lang_combo,$lang).'</p> '. 284 '</div>'. 179 $lposts 180 ->addColumn(new dcColumn('title',__('Title'),'post_title')) 181 ->addColumn(new dcColumn('cat',__('Category'),'cat_title')) 182 ->addColumn(new dcColumn('date',__('Date'),'post_date')) 183 ->addColumn(new dcColumn('datetime',__('Date and Time'),'post_dt')) 184 ->addColumn(new dcColumn('author',__('Author'),'user_id')) 185 ->addColumn(new dcColumn('status',__('Status'),'post_status')); 285 186 286 '<div class="cell filters-options">'.287 '<h4>'.__('Display options').'</h4>'.288 '<p><label for="sortby" class="ib">'.__('Order by:').'</label> '.289 form::combo('sortby',$sortby_combo,$sortby).'</p>'.290 '<p><label for="order" class="ib">'.__('Sort:').'</label> '.291 form::combo('order',$order_combo,$order).'</p>'.292 '<p><span class="label ib">'.__('Show').'</span> <label for="nb" class="classic">'.293 form::field('nb',3,3,$nb_per_page).' '.294 __('entries per page').'</label></p>'.295 '</div>'.296 '</div>'.297 187 298 '<p><input type="submit" value="'.__('Apply filters and display options').'" />'. 299 '<br class="clear" /></p>'. //Opera sucks 300 '</form>'; 188 $lposts->setup(); 301 189 302 # Show posts 303 $post_list->display($page,$nb_per_page, 304 '<form action="posts.php" method="post" id="form-entries">'. 190 $_ctx 191 ->setBreadCrumb(array(__('Entries') => 'posts.php')); 305 192 306 '%s'.307 193 308 '<div class="two-cols">'. 309 '<p class="col checkboxes-helpers"></p>'. 194 $core->tpl->display('posts.html.twig'); 310 195 311 '<p class="col right"><label for="action" class="classic">'.__('Selected entries action:').'</label> '.312 form::combo('action',$posts_actions_page->getCombo()).313 '<input type="submit" value="'.__('ok').'" /></p>'.314 form::hidden(array('user_id'),$user_id).315 form::hidden(array('cat_id'),$cat_id).316 form::hidden(array('status'),$status).317 form::hidden(array('selected'),$selected).318 form::hidden(array('attachment'),$attachment).319 form::hidden(array('month'),$month).320 form::hidden(array('lang'),$lang).321 form::hidden(array('sortby'),$sortby).322 form::hidden(array('order'),$order).323 form::hidden(array('page'),$page).324 form::hidden(array('nb'),$nb_per_page).325 $core->formNonce().326 '</div>'.327 '</form>',328 $show_filters329 );330 }331 196 332 dcPage::helpBlock('core_posts'); 333 dcPage::close(); 197 ?> -
admin/style/default.css
r2468 r2593 442 442 text-decoration: none; 443 443 border-bottom: 1px dotted #999; 444 } 445 a:hover, a:active, a:focus { 444 background-color: inherit; 445 outline: 0; 446 } 447 a:hover, a:active { 446 448 border-bottom-style: solid; 447 449 } 448 450 a img, a:link img, a:visited img { 449 451 border: none; 452 background: inherit; 450 453 } 451 454 h1 a:link, h1 a:visited { … … 455 458 color: #333; 456 459 } 460 a:link { 461 transition: .5s; 462 } 463 a:focus, a:focus img { 464 outline: 2px solid #bee74b; 465 border-bottom: none; 466 text-decoration: none; 467 } 457 468 /* ---------------------------------------------------------------------------- 458 469 FORMULAIRES 459 470 ---------------------------------------------------------------------------- */ 460 input[type=text], input[type=password], input[type=submit], 471 input[type=text], input[type=password], input[type=submit], 461 472 input[type=button], input[type=reset], a.button, button, textarea, select, legend { 462 border-radius: 3px; 473 border-radius: 3px; 463 474 max-width: 100%; 464 475 } … … 488 499 margin-bottom: 0.5em; 489 500 } 490 label .maximal, textarea.maximal, input.maximal {501 label .maximal, textarea.maximal, input.maximal, select.maximal { 491 502 width: 99%; 492 503 } … … 686 697 /* suppression, reset, "neutres" fond gris */ 687 698 button, input[type=button], input.button, 688 input[type=reset], input[type=submit].reset, input.reset, 699 input[type=reset], input[type=submit].reset, input.reset, 689 700 input[type=submit].delete, input.delete, 690 701 a.button, a.button.delete, a.button.reset { … … 699 710 button:hover, input[type=button]:hover, input.button:hover, 700 711 button:focus, input[type=button]:focus, input.button:focus, 701 input[type=reset]:hover, input[type=submit].reset:hover, input.reset:hover, 702 input[type=reset]:focus, input[type=submit].reset:focus, input.reset:focus, 712 input[type=reset]:hover, input[type=submit].reset:hover, input.reset:hover, 713 input[type=reset]:focus, input[type=submit].reset:focus, input.reset:focus, 703 714 input[type=submit].delete:hover, input.delete:hover, 704 715 input[type=submit].delete:focus, input.delete:focus, … … 930 941 color: #fff; 931 942 background: transparent url(dc_logos/b-dotclear120.png) no-repeat 0 6px; 943 transition: none; 932 944 } 933 945 h1 a:hover, h1 a:focus { 934 946 background-position: 0 -94px; 947 background-color: transparent; 948 transition: none; 935 949 } 936 950 /* top-info-blog */ … … 1277 1291 padding-right: 1.5em; 1278 1292 } 1279 th.first i mg{1293 th.first input { 1280 1294 padding-right: 34px; 1281 1295 } … … 1423 1437 background: #fff; 1424 1438 margin-bottom: 0; 1439 margin-top: 1em; 1425 1440 } 1426 1441 #login-screen input[type=text], #login-screen input[type=password], #login-screen input[type=submit], … … 1485 1500 #icons a:focus img, #icons a:hover img { 1486 1501 background: #bee74b; 1487 } 1488 #icons a:focus span, #icons a:hover span { 1502 outline: 0; 1503 border-color: #dadada; 1504 } 1505 #icons a:focus { 1506 outline: 0; 1507 border-color: #fff; 1508 } 1509 #icons a:hover span, #icons a:focus span { 1489 1510 border-bottom-style: solid; 1511 } 1512 #icons a:focus span { 1513 border: 2px solid #bee74b; 1490 1514 } 1491 1515 /* billet rapide */ … … 1611 1635 /* ------------------------------------------------------------------- blog_theme.php */ 1612 1636 /* pour les alignements verticaux */ 1613 #theme-new, #theme-activate, #theme-deactivate {1637 #theme-new, #theme-activate, #theme-deactivate, #theme-update { 1614 1638 margin-left: -10px; 1615 1639 margin-right: -10px; … … 1624 1648 background: #ecf0f1 url(texture.png); 1625 1649 } 1626 .module-name {1650 .module-name, .module-name label { 1627 1651 margin-bottom: .5em; 1652 color: #676e78; 1628 1653 } 1629 1654 .module-sshot { … … 1662 1687 margin-bottom: 1em; 1663 1688 } 1689 .module-name input[type="checkbox"] { 1690 margin-bottom: 0; 1691 } 1664 1692 /** 1665 1693 Les screenshots des thèmes ont deux tailles possibles : 1666 1694 - dans Ajouter des thèmes : 240px (+ 10 padding image + 20 padding boîte + 6 bordure + 2 ombrage = 278) 1667 1695 - dans Thèmes installés : 280px (+ 10 padding-image + 20 padding-boîte + 2 ombrage = 318) 1668 On adapte largeur et hauteur en fonction 1696 On adapte largeur et hauteur en fonction 1669 1697 */ 1670 #theme-new .box.theme { /* Ajouter un thème */1698 #theme-new .box.theme, #theme-update .box.theme { /* Ajouter un thème */ 1671 1699 width: 278px; 1672 1700 min-height: 275px; … … 1909 1937 } 1910 1938 /* upload multiple */ 1911 .enhanced_uploader .choose_files, .enhanced_uploader .cancel, 1939 .enhanced_uploader .choose_files, .enhanced_uploader .cancel, 1912 1940 .enhanced_uploader .clean, .enhanced_uploader .start { 1913 1941 margin-right: .4em; … … 2071 2099 } 2072 2100 .modules a.module-config { 2073 /* todo: add icon here */2074 padding: 4px 4px 0 20px;2101 background: transparent url(settings.png) no-repeat 2px 6px; 2102 padding: 4px 4px 0 18px; 2075 2103 } 2076 2104 #m_search { … … 2102 2130 .mod-more { 2103 2131 padding-top: .5em; 2132 } 2133 #plugin-update td { 2134 vertical-align: baseline; 2104 2135 } 2105 2136 /* ---------------------------------------------------------- post.php, page.php */ … … 2339 2370 } 2340 2371 .nav_prevnext a, a.back { 2372 color: #2373A8; 2341 2373 border: 1px solid #dfdfdf; 2342 2374 padding: 2px 1.5em; … … 2567 2599 border-color: #ffd478; 2568 2600 } 2569 /* ---------------------------------------------- Couleurs ajoutées via javascript 2601 /* ---------------------------------------------- Couleurs ajoutées via javascript 2570 2602 /* color-picker.js */ 2571 .color-color-picker { 2603 .color-color-picker { 2572 2604 border: 1px solid #000; 2573 width: 195px; 2574 background: #fff; 2605 width: 195px; 2606 background: #fff; 2575 2607 } 2576 2608 /* _media_item.js */ 2577 .color-div { 2609 .color-div { 2578 2610 border: 1px solid #ccc; 2579 2611 } 2580 2612 /* fadings ('color' est utilisé comme variable, pas comme text color) */ 2581 .colorBeginPassword, 2582 .colorBeginValidatorErr, 2613 .colorBeginPassword, 2614 .colorBeginValidatorErr, 2583 2615 .colorBeginUserMail { color: #fff; } 2584 .colorEndPassword, 2585 .colorEndError, 2586 .colorEndValidatorErr, 2616 .colorEndPassword, 2617 .colorEndError, 2618 .colorEndValidatorErr, 2587 2619 .colorEndUserMail { color: #ffbaba; } 2588 2620 .colorBeginMessage { color: #ccc; } 2589 .colorEndMessage, 2621 .colorEndMessage, 2590 2622 .colorBeginValidatorMsg { color: #676e78; } 2591 2623 .colorBeginError { color: #fefacd; } … … 2596 2628 UN POIL DE MEDIA QUERIES 2597 2629 ------------------------------------------------------------------------------------ */ 2598 @media screen and (min-width: 117em) {2599 body {2600 border: 1px solid #ccc;2601 border-top-width: 0;2602 }2603 }2604 2630 @media screen and (min-width: 80em) { 2605 html {2606 background: #fff;2607 }2608 body {2609 max-width: 140em;2610 margin: 0 auto;2611 }2612 2631 #wrapper { 2613 2632 background: #F7F7F7 url(bg_wrapper.png) repeat-y 18em; … … 2769 2788 vertical-align: bottom; 2770 2789 } 2790 .pseudo-tabs li { 2791 display: block; 2792 float: left; 2793 width: 50%; 2794 border-top: 1px solid #ddd; 2795 padding: .25em; 2796 } 2797 .pseudo-tabs li:first-child, .pseudo-tabs li:nth-of-type(2) { 2798 border-top: none; 2799 } 2771 2800 } 2772 2801 @media screen and (max-width: 26.5em) { … … 2837 2866 padding: 0.3em 1em 0.3em 0; 2838 2867 } 2868 .pseudo-tabs li { 2869 display: block; 2870 width: 100%; 2871 float: none; 2872 border-top: 1px solid #ddd !important; 2873 } 2874 .pseudo-tabs li:first-child { 2875 border-top: none; 2876 } 2839 2877 }
Note: See TracChangeset
for help on using the changeset viewer.