Changeset 3730:5c45a5df9a59 for admin
- Timestamp:
- 03/08/18 17:58:39 (8 years ago)
- Branch:
- default
- Location:
- admin
- Files:
-
- 19 edited
-
_charte.php (modified) (2 diffs)
-
blog_theme.php (modified) (8 diffs)
-
category.php (modified) (1 diff)
-
comments_actions.php (modified) (1 diff)
-
csp_report.php (modified) (2 diffs)
-
help.php (modified) (2 diffs)
-
index.php (modified) (1 diff)
-
install/check.php (modified) (1 diff)
-
media_item.php (modified) (1 diff)
-
plugin.php (modified) (1 diff)
-
plugins.php (modified) (8 diffs)
-
popup_link.php (modified) (1 diff)
-
post.php (modified) (1 diff)
-
post_media.php (modified) (1 diff)
-
posts_actions.php (modified) (1 diff)
-
services.php (modified) (2 diffs)
-
update.php (modified) (4 diffs)
-
user.php (modified) (1 diff)
-
xmlrpc.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
admin/_charte.php
r3685 r3730 11 11 # -- END LICENSE BLOCK ----------------------------------------- 12 12 13 require dirname(__FILE__) .'/../inc/admin/prepend.php';13 require dirname(__FILE__) . '/../inc/admin/prepend.php'; 14 14 15 15 dcPage::check('usage,contentadmin'); … … 19 19 <head> 20 20 <meta charset="UTF-8" /> 21 <meta name="ROBOTS" content="NOARCHIVE,NOINDEX,NOFOLLOW" />22 <meta name="GOOGLEBOT" content="NOSNIPPET" />23 <meta name="viewport" content="width=device-width, initial-scale=1.0" />24 <title>Bibliothèque de styles - Dotclear - 2.7</title>25 <link rel="icon" type="image/png" href="images/favicon96-login.png" />26 <link rel="stylesheet" href="style/default.css" type="text/css" media="screen" />27 <?php28 $core->auth->user_prefs->addWorkspace('interface');29 if ($core->auth->user_prefs->interface->htmlfontsize) {30 echo31 '<script type="text/javascript">'."\n".32 dcPage::jsVar('dotclear_htmlFontSize',$core->auth->user_prefs->interface->htmlfontsize).33 "</script>\n";34 }35 ?>36 <script type="text/javascript" src="js/jquery/jquery.js"></script>37 <script type="text/javascript" src="js/jquery/jquery-ui.custom.js"></script>38 <script type="text/javascript" src="js/jquery/jquery.ui.touch-punch.js"></script>39 <script type="text/javascript" src="js/jquery/jquery.pageTabs.js"></script>40 <script type="text/javascript" src="js/jquery/jquery.biscuit.js"></script>41 <script type="text/javascript" src="js/common.js"></script>42 <script type="text/javascript" src="js/prelude.js"></script>43 <script type="text/javascript">44 dotclear.img_plus_alt = 'dévoiler';45 dotclear.img_minus_alt = 'cacher';46 dotclear.img_menu_on = 'images/menu_on.png';47 dotclear.img_menu_off = 'images/menu_off.png';48 dotclear.msg.new_window = 'nouvelle fenêtre';49 </script>50 <script type="text/javascript">51 $(function() {52 $.pageTabs('two-boxes');53 $('#pageslist').sortable({'cursor':'move'});54 $('#pageslist tr').hover(function(){55 $(this).css({'cursor':'move'});56 }, function(){57 $(this).css({'cursor':'auto'});58 });59 $('#pageslist tr td input.position').hide();60 $('#pageslist tr td.handle').addClass('handler');61 });62 </script>21 <meta name="ROBOTS" content="NOARCHIVE,NOINDEX,NOFOLLOW" /> 22 <meta name="GOOGLEBOT" content="NOSNIPPET" /> 23 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 24 <title>Bibliothèque de styles - Dotclear - 2.7</title> 25 <link rel="icon" type="image/png" href="images/favicon96-login.png" /> 26 <link rel="stylesheet" href="style/default.css" type="text/css" media="screen" /> 27 <?php 28 $core->auth->user_prefs->addWorkspace('interface'); 29 if ($core->auth->user_prefs->interface->htmlfontsize) { 30 echo 31 '<script type="text/javascript">' . "\n" . 32 dcPage::jsVar('dotclear_htmlFontSize', $core->auth->user_prefs->interface->htmlfontsize) . 33 "</script>\n"; 34 } 35 ?> 36 <script type="text/javascript" src="js/jquery/jquery.js"></script> 37 <script type="text/javascript" src="js/jquery/jquery-ui.custom.js"></script> 38 <script type="text/javascript" src="js/jquery/jquery.ui.touch-punch.js"></script> 39 <script type="text/javascript" src="js/jquery/jquery.pageTabs.js"></script> 40 <script type="text/javascript" src="js/jquery/jquery.biscuit.js"></script> 41 <script type="text/javascript" src="js/common.js"></script> 42 <script type="text/javascript" src="js/prelude.js"></script> 43 <script type="text/javascript"> 44 dotclear.img_plus_alt = 'dévoiler'; 45 dotclear.img_minus_alt = 'cacher'; 46 dotclear.img_menu_on = 'images/menu_on.png'; 47 dotclear.img_menu_off = 'images/menu_off.png'; 48 dotclear.msg.new_window = 'nouvelle fenêtre'; 49 </script> 50 <script type="text/javascript"> 51 $(function() { 52 $.pageTabs('two-boxes'); 53 $('#pageslist').sortable({'cursor':'move'}); 54 $('#pageslist tr').hover(function(){ 55 $(this).css({'cursor':'move'}); 56 }, function(){ 57 $(this).css({'cursor':'auto'}); 58 }); 59 $('#pageslist tr td input.position').hide(); 60 $('#pageslist tr td.handle').addClass('handler'); 61 }); 62 </script> 63 63 </head> 64 64 65 <body id="dotclear-admin" class="no-js guideline<?php $core->auth->user_prefs->interface->dynfontsize ? ' responsive-font' : ''; ?>">66 <ul id="prelude">67 <li><a href="#content">Aller au contenu</a></li>68 <li><a href="#main-menu">Aller au menu</a></li>69 <li><a href="#qx">Aller à la recherche</a></li>70 </ul>71 <div id="header">72 <h1><a href="./index.php"><span class="hidden">Dotclear</span></a></h1>73 <div id="top-info-blog">74 <p>Bibliothèque de styles - Dotclear - 2.6+</p>75 </div>76 <ul id="top-info-user"><li>Octobre 2013</li></ul>77 </div><!-- /header -->78 79 <div id="wrapper" class="clearfix">80 <div class="hidden-if-no-js collapser-box"><button type="button" id="collapser" class="void-btn">81 <img class="collapse-mm visually-hidden" src="images/collapser-hide.png" alt="Cacher le menu" />82 <img class="expand-mm visually-hidden" src="images/collapser-show.png" alt="Montrer le menu" />83 </button></div>84 <div id="main">85 <div id="content" class="clearfix">86 <h2>Typographie</h2>87 <h3 id="texte">Textes</h3>88 <p>La font-size de base est à 1.2rem (la valeur <code>1rem</code> correspond à 10px). Si vous utilisez l'unité <code>rem</code> pensez à faire précéder la déclaration par son équivalent89 en pixels pour rester compatible avec Internet Explorer. L'interlignage courant est à 1.5.</p>90 <p>La liste suivante est de class <code>"nice"</code>. Elle est semblable aux listes ordinaires mais avec des puces carrées.</p>91 <ul class="nice">92 <li>Les textes courants sont en Arial, Helvetica ou sans-serif. </li>93 <li>Le code adopte la fonte Andale Mono, Courier New ou monospace.</li>94 <li>Les liens ont des aspects différents au focus et au survol. Il faut conserver cette distinction, nécessaire à l'accessibilité et l'ergonomie.</li>95 </ul>96 97 <h3 id="titres">Titre h3</h3>98 <p>Le titre de niveau h1 est réservé au titre du site-admin. Le titre de niveau h2 est réservé au breadcrumb/titre de la page courante. On utilise les titres de niveau h3 en premier niveau de titre à l'intérieur des pages, comme sur la page Import/Export.</p>99 <p>Il ne faut pas choisir un niveau de titre en fonction de son aspect mais respecter une hiérarchie cohérente. On peut obtenir visuellement l'aspect d'un titre h3 en donnant à l'élément la class <code>"as_h3"</code>.</p>100 <h4>Titre de niveau h4</h4>101 <p>On peut obtenir visuellement l'aspect d'un titre h4 en donnant à l'élément la class <code>"as_h4"</code>.</p>102 <h5>Titre de niveau h5</h5>103 <p>Le titre de niveau h5 est assez peu employé mais son style est prévu. Dans une admin de base, on utilise les niveaux104 h5 pour certains éléments du sidebar du billet, mais un style particulier leur est alors appliqué pour ressembler aux autres105 items de ce sidebar.</p>106 <div class="fieldset">107 <h4>Titres des encadrés</h4>108 <p>Les titres de boîte encadrées (div de class <code>"fieldset"</code>, comme ici) se présentent comme ci-dessus.</p>109 <p>On peut utiliser, quel que soit le niveau hx de cet intertitre la class <code>"pretty-title"</code> pour obtenir l'effet ci-dessus.</p>110 </div>111 <h4 class="smart-title">Autre variante</h4>112 <p>On dispose également d'une class <code>"smart-title"</code> pour obtenir une présentation comme celle du titre de ce paragraphe.</p>113 114 <h2>Layouts</h2>115 116 <h3 id="onglets">Onglets</h3>117 <p>Les descriptions des constructions en multi-colonnes ci-dessous présentent un exemple de répartition en onglets.</p>118 <p>Chacun de ces onglets doit être défini à l'aide d'une <code><div class="multi-part"></code>. Ils seront alors automatiquement présentés sous forme d'onglets.</p>119 120 <h3 id="multi-colonnage">Multi-colonnage</h3>121 <div id="one-box" class="multi-part" title="One-box">122 <h4>Boîtes distribuées horizontalement</h4>123 <div class="one-box">124 <div class="box">125 <p><span class="step">1</span> Toutes les boîtes de class <code>"box"</code> placées à l'intérieur d'une boîte de class <code>"one-box"</code> se distribuent horizontalement (imaginez que chaque boîte est un mot dans un paragraphe). Si les largeurs de ces boîtes ne sont pas spécifiquement définies dans la CSS, elle s'ajustent à leur contenu.</p>126 </div>127 <div class="box">128 <p><span class="step">2</span> Voici une petite boîte.</p>129 </div>130 <div class="box">131 <p><span class="step">3</span> Une autre petite boîte.</p>132 </div>133 <div class="box">134 <p><span class="step">4</span> Par défaut les « lignes » de boîtes <code>"box"</code> sont justifiées au sein de la boîte <code>"one-box"</code> et l'espacement se répartit entre elles.</p>135 </div>136 <div class="box">137 <p><span class="step">5</span> Si vous souhaitez un autre alignement des boîtes entre elles vous pouvez ajouter les class :</p>138 <ul class="nice clear">139 <li><code>"txt-left"</code>,</li>140 <li><code>"txt-right"</code></li>141 <li>ou <code>"txt-center"</code></li>142 </ul>143 <p>à la class <code>"one-box"</code>.</p>144 </div>145 <div class="box">146 <p><span class="step">6</span> Le cadre placé ici autour de chaque boîte ne fait pas partie des styles par défaut.</p>147 </div>148 </div>149 </div>150 <div id="two-boxes" class="multi-part" title="Two-boxes">151 <h4>Boîtes distribuées deux par deux</h4>152 <div>153 <div class="two-boxes odd">154 <p><span class="step">1</span> Les boîtes de class <code>"two-boxes"</code> ont une règle CSS <code>display:inline-block;</code>. Elles se rangent alternativement à gauche et à droite. Pour plus de clarté, les blocs sont ici numérotés avec leur ordre dans le flux.</p>155 </div><!--156 --><div class="two-boxes even">157 <p><span class="step">2</span> On peut assortir une boîte des class <code>"odd"</code> (nothing left) et <code>"even"</code> pour que les marges se placent correctement.</p>158 </div><!--159 --><div class="two-boxes odd">160 <p><span class="step">3</span> Attention, il faut soit ne pas retourner à la ligne entre la fermeture d'une boîte <code>"two-boxes"</code> et l'ouverture de la suivante soit adopter la méthode de commentaire vide mise en place ici et expliquée chez <a href="http://www.alsacreations.com/astuce/lire/1432-display-inline-block-espaces-indesirables.html">Alsacréations</a> (« Méthode 2 »).</p>161 </div><!--162 --><div class="two-boxes even">163 <div class="two-boxes odd">164 <p><span class="step">4</span> On peut bien sûr imbriquer des boîtes de class <code>"two-boxes"</code>165 au sein d'une boîte <code>"two-boxes" afin qu'elles…</code>…</p>166 </div><div class="two-boxes even">167 <p><span class="step">4 bis</span>… se distribuent horizontalement comme dans une boîte <code>"one-box"</code>.</p>168 </div>169 </div>170 </div>171 </div>172 <div id="three-boxes" class="multi-part" title="Three-boxes">173 <h4>Boîtes distribuées trois par trois</h4>174 <div>175 <div class="three-boxes">176 <div class="box">177 <p>Sur le même principe que les « two-boxes » on peut utiliser des boîtes de class <code>"three-boxes"</code> pour répartir les contenus sur trois colonnes de 30% chacune (le reste est occupé par les marges).</p>178 </div>179 </div><!--180 --><div class="three-boxes">181 <div class="box">182 <p>Comme pour les "two-boxes" il faut soit ne pas laisser d'espace ou de retour à la ligne entre les boîtes, soit adopter la méthode recommandée plus haut.</p>183 </div>184 </div><!--185 --><div class="three-boxes">186 <div class="box">187 <p>Dans les « two-boxes » comme dans les « three-boxes », on peut placer à l'intérieur plusieurs autres div de class="box" qui s'afficheront les unes à côté des autres ou l'une en dessous de l'autre selon la place dont elles disposent.</p>188 </div>189 </div>190 </div>191 </div>192 <div id="two-cols-50-50" class="multi-part" title="Two-cols (50/50)">193 <h4>Deux colonnes flottantes de largeurs égales</h4>194 <div class="two-cols clearfix">195 <div class="col">196 <p>La div englobante porte la class <code>"two-cols"</code>, chacune de ses div porte la class <code>"col"</code>.197 Sans autre précision les deux colonnes sont d'égale largeur.</p>198 </div>199 <div class="col">200 <p>Attention : ces colonnes sont construites avec des flottants, il faut donc penser à mettre une class <code>clear</code> à l'élément suivant ou ajouter la class <code>"clearfix"</code> à la <code>div class="two-cols"</code>.</p>201 </div>202 </div>203 </div>204 <div id="two-cols-70-30" class="multi-part" title="Two-cols (70/30)">205 <h4>Deux colonnes flottantes de largeurs inégales</h4>206 <div class="two-cols clearfix">207 <div class="col70">208 <p><span class="step">col70</span> La div englobante porte la class <code>"two-cols"</code>.209 Pour obtenir des colonnes inégales, on dispose des classes <code>"col70"</code> et <code>col30</code> à attribuer à l'une ou à l'autre de ses colonnes.</p>210 </div>211 <div class="col30">212 <p><span class="step">col30</span> Penser à mettre une class <code>"clear"</code> à l'élément suivant ou ajouter la class <code>"clearfix"</code> <code>div class="two-cols"</code>.</p>213 </div>214 </div>215 </div>216 <div id="three-cols" class="multi-part" title="Three-cols (deprecated)">217 <h4>Trois colonnes flottantes de largeurs égales</h4>218 <p class="warning"><strong>Deprecated.</strong> Ces règles sont conservées dans la 2.6 par souci de rétro-compatibilité mais il est recommandé d'utiliser désormais le colonnage <a href="#three-boxes">three-boxes</a>.</p>219 <div class="three-cols clearfix">220 <div class="col">221 <h5>Colonne 1</h5>222 <p>La div englobante porte la class <code>"three-cols"</code>, chacune de ses div porte la class <code>"col"</code>. Les trois colonnes sont d'égale largeur.</p>223 </div>224 <div class="col">225 <h5>Colonne 2</h5>226 <p>Voici une deuxième colonne. N'oubliez pas d'ajouter la class <code>"clearfix"</code> à la class <code>"three-cols"</code> ou un élément de class <code>"clear"</code> après cet élément.</p>227 </div>228 <div class="col">229 <h5>Colonne 3</h5>230 <p>Voilà la troisième colonne.</p>231 </div>232 </div>233 </div>234 <hr />235 <p><strong>Note :</strong> dans les exemples les valeurs et les numérotations sont placées dans un <code>span class="step"</code> (et ressortent donc dans un petit bloc à fond gris).</p>236 237 <h2>Interactions</h2>238 239 <h3 id="elements">Éléments de formulaire</h3>240 <form class="two-cols clearfix" action="#">241 <div class="col">242 <p><label for="ex1">Label simple + input text :</label><input id="ex1" type="text" /></p>243 <p class="form-note">p class="form-note".</p>244 <p><label for="ex4" class="classic">Label class="classic" + input text :</label> <input id="ex4" type="text" /></p>245 <p><label for="ex2" class="required"><abbr title="Champ obligatoire">*</abbr> Label class="required" :</label> <input id="ex2" type="text" required placeholder="exemple" /><span class="form-note">span class="form-note"</span></p>246 <p><label for="ex11" class="bold">Label class="bold" :</label> <input id="ex11" type="text" /></p>247 <p class="form-note">La class="bold" est bien sûr à écrire en minuscules.</p>248 <p><label for="ex3">Input class="maximal" :</label> <input id="ex3" type="text" class="maximal" /></p>249 </div>250 <div class="col">251 <p class="field"><label for="ex5">p.field label + input :</label><input id="ex5" type="text" /></p>252 <p class="field"><label for="ex6">p.field label + select :</label>253 <select id="ex6"><option value="opt2">Option 2</option><option selected="selected" value="opt2">Option 2</option></select>254 </p>255 <p><label class="classic" for="ex7"><input type="checkbox" checked="checked" id="ex7" value="1" name="ex7" />256 Checkbox (label.classic)</label></p>257 <p><label class="classic" for="ex8-1"><input type="radio" checked="checked" id="ex8-1" value="ex8-1" name="ex8-1" />258 Bouton radio 1 (label.classic)</label></p>259 <p><label class="classic" for="ex8-2"><input type="radio" id="ex8-2" value="ex8-2" name="ex8-2" />260 Bouton radio 2 (label.classic)</label></p>261 <p class="form-note">Les checkboxes et les boutons radio sont dans la balise <label>.</p>262 <p><label class="classic" for="ex9"><input type="checkbox"263 checked="checked" id="ex9" value="1" title="intitulé du champ" /></label> <label264 for="ex10" class="classic">checkbox.classic + label class="classic" :</label> <input id="ex10" type="text" /></p>265 </div>266 </form>267 <form action="#" class="clear">268 <fieldset>269 <legend>Légende de fieldset</legend>270 <p>Attention: Les fieldsets ne doivent être utilisés que pour isoler un groupe de champs au sein d'un formulaire.</p>271 </fieldset>272 </form>273 274 <h3 id="boutons">Boutons</h3>275 <div class="clearfix">276 <p><a class="button add">a.button.add</a> Se place en haut à droite (dans un p.top-add)</p>277 <p><input type="button" value="Type button" /> <a href="#" class="button">a.button</a> <input type="reset" value="Type reset" /> <a href="#" class="button reset">a.reset</a></p>278 <p><input type="submit" value="Type submit" /> <input type="submit" class="delete" value="Type submit class delete" /> <a href="#" class="button delete">a.button delete</a></p>279 <p><input type="submit" value="Type submit class disabled" class="disabled" /></p>280 </div>281 282 <h3 id="messages">Messages</h3>283 <h4 class="smart-title">Messages système</h4>284 <p>Il existe quatre types de messages système auxquels correspondent des classes CSS : .error, .message, .success, .warning-msg. Ils s'affichent en haut de page, sous le titre/breadcrumb.</p>285 <div class="message">286 <p>Message simple. Le plus souvent horodaté dcPage::message</p>287 </div>288 <div class="success">289 <p>Message de succès. Le plus souvent horodaté dcPage::success</p>290 </div>291 <div class="warning-msg">292 <p>Message warning. Non horodaté dcPage::warning</p>293 </div>294 <div class="error">295 <p>Message d'erreur. Non horodaté dcPage::error</p>296 </div>297 <p>La classe .static-msg peut être utilisée directement pour affichage en haut de page :</p>298 <div class="static-msg">299 <p>Comme le message simple mais sans effets de transition.</p>300 </div>301 <p>Un type de message réservé à Dotclear peut s'afficher en haut de la page :</p>302 <div class="dc-update">303 <h3>Dotclear 42 est disponible</h3>304 <p><a class="button submit" href="#">Mettre à jour maintenant</a>305 <a class="button" href="u#">Me le rappeler plus tard</a></p>306 <p class="updt-info"><a href="#">Informations sur cette version</a></p>307 </div>308 <h4 class="smart-title">Messages contextuels</h4>309 <p class="warn">Paragraphe de message d'alerte class warn ou warning.</p>310 <p class="info">Paragraphe de message de class info.</p>311 <p>Ces messages sont en display:inline-block. Le fond s'adapte à la longueur du message.</p>312 313 <h2>Navigation</h2>314 315 <h3 id="direct">Selecteur d'accès direct</h3>316 <p>Sur des pages longues et denses comme les pages about:config ou about:preferences, on peut utiliser un sélecteur pour faciliter l'accès direct aux sections.</p>317 <p class="anchor-nav">318 <label class="classic" for="lp_nav">Aller à : </label>319 <select id="lp_nav" name="lp_nav">320 <option value="#l_accessibility">accessibility</option>321 <option value="#l_dashboard">dashboard</option>322 <option value="#l_dmhostingmonitor">dmhostingmonitor</option>323 <option value="#l_dmpending">dmpending</option>324 <option value="#l_favorites">favorites</option>325 <option value="#l_filters">filters</option>326 <option value="#l_interface">interface</option>327 <option value="#l_lists">lists</option>328 <option value="#l_toggles">toggles</option>329 </select>330 <input type="submit" id="lp_submit" value="Ok" style="display: none;" />331 <input type="hidden" value="aboutConfig" name="p" />332 </p>333 <h3 id="prevnext">Navigation contextuelle</h3>334 <p><a title="Titre du lien" href="http://fr.dotclear.org/blog" class="onblog_link outgoing">Lien vers le blog <img alt="" src="images/outgoing-blue.png" /></a></p>335 <p class="nav_prevnext"><a title="Titre de l'élément précédente" href="post.php?id=4145">« Élément précédent</a> | <a title="Titre de l'élément suivant" href="#">Élément suivant »</a></p>336 337 <h3 id="pseudo-tabs">Pseudo-onglets </h3>338 <p>Les pseudo-onglets permettent d'ajouter des sous-pages qui sont des liens vers d'autres pages, par opposition aux onglets qui sont des sections internes à la page.</p>339 <p>Les pseudo-onglets sont à positionner immédiatement après le breadcrumb (ici un hr simule le trait sous le breadcrumb).</p>340 <p>Ces pseudo-onglets doivent être définis avec un <code><ul class="pseudo-tabs"></code> et des <code><li></code>.</p>341 <hr style="margin-bottom: .75em;" />342 <ul class="pseudo-tabs">343 <li><a href="#">Page 1</a></li>344 <li><a href="#">Autre faux onglet</a></li>345 <li><a href="#" class="active">Onglet actif</a></li>346 <li><a href="#">Liste 4</a></li>347 </ul>348 349 <h2 id="common">Tableaux</h2>350 <p>Il existe deux mises en forme type de tableaux selon que l'on cherche à faire un tableau ordinaire351 ou un tableau dont on peut déplacer les lignes par glisser déposer (voir plus bas). Cependant certaines règles352 sont communes à tout les tableaux.</p>353 354 <h3>Règles communes</h3>355 <h4>Largeur du tableau</h4>356 <p>Sauf pour des tableaux particuliers (absents dans l'admin mais qui pourraient être nécessaires357 à un plugin,les tableaux occupent toute la largeur de la page. Afin que les tableaux soient consultables358 sur un mobile en navigant horizontalement, on englobe le tableau dans une <code>div class="table-outer"</code>,359 qui servira de « conteneur ».</p>360 <h4>Accessibilité</h4>361 <p>Les éléments caption, th, scope sont nécessaires à l'accessibilité. Ne les oubliez pas ! ».362 On peut utiliser la <code>class="hidden"</code> sur l'élément <code>caption</code> (qui accueille363 le titre du tableau) si vous ne souhaitez pas qu'il soit affiché sur la page.</p>364 <h4>Les classes</h4>365 <p>Des classes particulières peuvent être attribuées aux lignes :</p>366 <ul>367 <li><code>line</code> (systématique) : pour les traits horizontaux et le fond gris léger368 au survol ;</li>369 <li><code>offline</code> : pour un noir estompé (gris quoi).</li>370 </ul>371 <p>Des classes particulières peuvent être appliquées aux cellules :</p>372 <ul>373 <li><code>nowrap</code> : pas de retour à la ligne dans la cellule, quelle que soit la374 largeur de la page ;</li>375 <li><code>maximal</code> : la cellule prendra toute la largeur restante disponible ;</li>376 <li><code>count</code> : le contenu de la cellule sera aligné à droite avec un petit retrait.</li>377 </ul>378 <h3 id="courants">Tableau classique</h3>379 <div class="table-outer">380 <table>381 <caption class="hidden">Liste des entrées</caption>382 <tr>383 <th colspan="2" class="first">Titre</th>384 <th scope="col">Date</th>385 <th scope="col">Catégorie</th>386 <th scope="col">Auteur</th>387 <th scope="col">Commentaires</th>388 <th scope="col">Rétroliens</th>389 <th scope="col">État</th>390 </tr>391 <tr class="line">392 <td class="nowrap"><input type="checkbox" name="name1" value="value1" /></td>393 <td class="maximal" scope="row"><a href="#">Mon cher Franck</a></td>394 <td class="nowrap count">06/08/2013 19:16</td>395 <td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>396 <td class="nowrap">kozlika</td><td class="nowrap count">4</td>397 <td class="nowrap count">0</td><td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> <img alt="Sélectionné" title="Sélectionné" src="images/selected.png" /> </td>398 </tr>399 <tr class="line offline">400 <td class="nowrap"><input type="checkbox" name="name2" value="value2" /></td>401 <td class="maximal" scope="row"><a href="#">Dotclear 2.3.0</a></td>402 <td class="nowrap count">16/05/2011 22:29</td>403 <td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>404 <td class="nowrap">kozlika</td><td class="nowrap count">5</td>405 <td class="nowrap count">0</td><td class="nowrap status"><img alt="Non publié" title="Non publié" src="images/check-off.png" /> <img alt="Sélectionné" title="Sélectionné" src="images/selected.png" /> </td>406 </tr>407 <tr class="line">408 <td class="nowrap"><input type="checkbox" name="entries[]" value="2148" /></td>409 <td class="maximal" scope="row"><a href="#">Causons opéra au Tamm Bara</a></td>410 <td class="nowrap count">24/11/2009 23:10</td>411 <td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>412 <td class="nowrap">kozlika</td>413 <td class="nowrap count">4</td><td class="nowrap count">1</td>414 <td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> </td>415 </tr>416 <tr class="line">417 <td class="nowrap"><input type="checkbox" name="entries[]" value="2136" /></td>418 <td class="maximal" scope="row"><a href="#">Souffler six bougies</a></td>419 <td class="nowrap count">14/08/2009 00:00</td><td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>420 <td class="nowrap">kozlika</td>421 <td class="nowrap count">4</td><td class="nowrap count">2</td><td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> </td>422 </tr>423 <tr class="line">424 <td class="nowrap"><input type="checkbox" name="entries[]" value="2129" /></td>425 <td class="maximal" scope="row"><a href="#">Dotclear et grenadine, troisième édition</a></td>426 <td class="nowrap count">15/06/2009 07:39</td>427 <td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>428 <td class="nowrap">kozlika</td>429 <td class="nowrap count">9</td>430 <td class="nowrap count">1</td>431 <td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> </td>432 </tr>433 <tr class="line">434 <td class="nowrap"><input type="checkbox" name="entries[]" value="2111" /></td>435 <td class="maximal" scope="row"><a href="#">L'abc dotclear est né</a></td>436 <td class="nowrap count">19/03/2009 10:31</td><td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>437 <td class="nowrap">kozlika</td>438 <td class="nowrap count">1</td><td class="nowrap count">0</td>439 <td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> </td>440 </tr>441 </table>442 </div>443 444 <h3 id="dragable">Tableau avec ordonnancement</h3>445 <p>Les tableaux permettant l'ordonnancement doivent offrir la possibilité d'effectuer le classement grâce à446 des inputs placés en début de ligne pour que le classement soit possible même lorsque cette fonctionnalité est447 désactivée (via les préférences utilisateurs, voire une désactivation complète du javascript dans le navigateur).</p>448 <div class="table-outer">449 <table class="maximal dragable">450 <thead>451 <tr>452 <th colspan="3">Titre</th>453 <th>Date</th>454 <th>Auteur</th>455 <th>Commentaires</th>456 <th>Rétroliens</th>457 <th>État</th>458 </tr>459 </thead>460 <tbody id="pageslist">461 <tr class="line" id="p10899">462 <td class="nowrap handle minimal">463 <input type="text" size="2" name="order[10899]" maxlength="3" value="1" class="position" title="position de Mentions légales" />464 </td>465 <td class="nowrap">466 <input type="checkbox" name="entries[]" value="10899" title="Sélectionner cette page" />467 </td>468 <td class="maximal"><a href="#">Mentions légales</a>469 </td>470 <td class="nowrap">17/12/2008 07:35</td>471 <td class="nowrap">franck</td>472 <td class="nowrap">0</td>473 <td class="nowrap">0</td>474 <td class="nowrap status">475 <img alt="Publié" title="Publié" src="images/check-on.png" />476 </td>477 </tr>478 <tr class="line" id="p10937">479 <td class="nowrap handle minimal">480 <input type="text" size="2" name="order[10937]" maxlength="3" value="2" class="position" title="position de Page active et cachée" />481 </td>482 <td class="nowrap">483 <input type="checkbox" name="entries[]" value="10937" title="Sélectionner cette page" />484 </td>485 <td class="maximal"><a href="#">Page active et cachée</a>486 </td>487 <td class="nowrap">26/10/2012 11:08</td>488 <td class="nowrap">admin</td>489 <td class="nowrap">0</td>490 <td class="nowrap">0</td>491 <td class="nowrap status">492 <img alt="Publié" title="Publié" src="images/check-on.png" />493 <img alt="Masqué" title="Masqué" src="images/hidden.png" />494 </td>495 </tr>496 <tr class="line offline" id="p11047">497 <td class="nowrap handle minimal">498 <input type="text" size="2" name="order[11047]" maxlength="3" value="3" class="position" title="position de Page révisionnable" />499 </td>500 <td class="nowrap">501 <input type="checkbox" name="entries[]" value="11047" title="Sélectionner cette page" />502 </td>503 <td class="maximal"><a href="#">Page révisionnable</a>504 </td>505 <td class="nowrap">14/12/2012 13:26</td>506 <td class="nowrap">admin</td>507 <td class="nowrap">0</td>508 <td class="nowrap">0</td>509 <td class="nowrap status">510 <img alt="En attente" title="En attente" src="images/check-wrn.png" />511 </td>512 </tr>513 <tr class="line offline" id="p10939">514 <td class="nowrap handle minimal">515 <input type="text" size="2" name="order[10939]" maxlength="3" value="4" class="position" title="position de Programme" />516 </td>517 <td class="nowrap">518 <input type="checkbox" name="entries[]" value="10939" title="Sélectionner cette page" />519 </td>520 <td class="maximal"><a href="#">Programme</a>521 </td>522 <td class="nowrap">26/10/2020 11:23</td>523 <td class="nowrap">admin</td>524 <td class="nowrap">0</td>525 <td class="nowrap">0</td>526 <td class="nowrap status">527 <img alt="Programmé" title="Programmé" src="images/scheduled.png" />528 </td>529 </tr>530 <tr class="line offline" id="p10940">531 <td class="nowrap handle minimal">532 <input type="text" size="2" name="order[10940]" maxlength="3" value="5" class="position" title="position de Protégée" />533 </td>534 <td class="nowrap">535 <input type="checkbox" name="entries[]" value="10940" title="Sélectionner cette page" />536 </td>537 <td class="maximal"><a href="#">Protégée</a>538 </td>539 <td class="nowrap">26/10/2012 11:23</td>540 <td class="nowrap">admin</td>541 <td class="nowrap">0</td>542 <td class="nowrap">0</td>543 <td class="nowrap status">544 <img alt="En attente" title="En attente" src="images/check-wrn.png" />545 <img alt="Protégé" title="Protégé" src="images/locker.png" />546 </td>547 </tr>548 </tbody>549 </table>550 </div>551 552 <h2 id="iconset">Icônes</h2>553 <p>Les icônes utilisées dans l'administration sont présentes en deux formats 64*64px pour les grandes554 (qui sont affichées sur le tableau de bord si la page correspondante est choisie en favori par l'utilisateur) et555 16*16px pour les petits formats.</p>556 <p>La plupart sont dérivées de la fonte d'icônes <a href="http://www.elegantthemes.com/blog/resources/elegant-icon-font">Elegant Font</a>. Les autres sont des images vectorielles réalisées557 par la DC Team. Nous les avons nommées <em>Traviata</em>. La palette de couleurs utilisée est la suivante :</p>558 <p class="txt-center"><img src="images/palette-traviata.png" alt="palette des couleurs utilisées pour les icônes" /></p>559 <p class="txt-center">Bleu : #137bbb - Vert : #9ac123 - Rouge : #c44d58 - Bleu ciel : #a2cbe9 - Gris clair : #ececec -560 Gris moyen : #b2b2b2 - Gris foncé : #676e78.</p>561 </div><!-- /content -->562 </div><!-- /main -->563 <div id="main-menu">564 <ul><li class="pretty-title">Typographie565 <ul>566 <li><a href="#texte">Texte</a></li>567 <li><a href="#titres">Titres hx</a></li>568 </ul>569 </li>570 <li class="pretty-title">Layouts571 <ul>572 <li><a href="#onglets">Onglets</a></li>573 <li><a href="#multi-colonnage">Multi-colonnage</a></li>574 </ul>575 </li>576 <li class="pretty-title">Interactions577 <ul>578 <li><a href="#elements">Éléments de formulaire</a></li>579 <li><a href="#boutons">Boutons</a></li>580 <li><a href="#messages">Messages</a></li>581 </ul>582 </li>583 <li class="pretty-title">Navigation584 <ul>585 <li><a href="#direct">Accès direct</a></li>586 <li><a href="#prevnext">Précédent, suivant</a></li>587 <li><a href="#pseudo-tabs">Pseudo-onglets</a></li>588 </ul>589 </li>590 <li class="pretty-title">Tableaux591 <ul>592 <li><a href="#commons">Règles communes</a></li>593 <li><a href="#courants">Tableaux courants</a></li>594 <li><a href="#dragables">Tableaux ordonnancés</a></li>595 </ul>596 </li>597 </ul>598 <div class="info vertical-separator">599 <p>Cette page vise à présenter les règles graphiques et conventions utilisées dans les pages de l'administration600 d'une installation Dotclear, à l'usage des contributeurs et développeurs d'extensions. Elle en est elle-même601 une illustration. L'observation de son code source peut donc servir de complément aux descriptions.</p>602 </div>603 </div><!-- /main-menu -->604 605 <div id="footer">606 <a href="http://dotclear.org/" title="Merci de manger des clafoutis."><img src="style/dc_logos/w-dotclear90.png" alt="Merci d'utiliser Dotclear 2.6-dev." /></a>607 </div><!-- /footer -->608 <!--609 .610 ,;:'`'::611 __||612 _____/LLLL\_613 \__________"|614 ~^~^~^~^~^~^~^~^~^~615 -->616 </div><!-- /wrapper -->65 <body id="dotclear-admin" class="no-js guideline<?php $core->auth->user_prefs->interface->dynfontsize ? ' responsive-font' : '';?>"> 66 <ul id="prelude"> 67 <li><a href="#content">Aller au contenu</a></li> 68 <li><a href="#main-menu">Aller au menu</a></li> 69 <li><a href="#qx">Aller à la recherche</a></li> 70 </ul> 71 <div id="header"> 72 <h1><a href="./index.php"><span class="hidden">Dotclear</span></a></h1> 73 <div id="top-info-blog"> 74 <p>Bibliothèque de styles - Dotclear - 2.6+</p> 75 </div> 76 <ul id="top-info-user"><li>Octobre 2013</li></ul> 77 </div><!-- /header --> 78 79 <div id="wrapper" class="clearfix"> 80 <div class="hidden-if-no-js collapser-box"><button type="button" id="collapser" class="void-btn"> 81 <img class="collapse-mm visually-hidden" src="images/collapser-hide.png" alt="Cacher le menu" /> 82 <img class="expand-mm visually-hidden" src="images/collapser-show.png" alt="Montrer le menu" /> 83 </button></div> 84 <div id="main"> 85 <div id="content" class="clearfix"> 86 <h2>Typographie</h2> 87 <h3 id="texte">Textes</h3> 88 <p>La font-size de base est à 1.2rem (la valeur <code>1rem</code> correspond à 10px). Si vous utilisez l'unité <code>rem</code> pensez à faire précéder la déclaration par son équivalent 89 en pixels pour rester compatible avec Internet Explorer. L'interlignage courant est à 1.5.</p> 90 <p>La liste suivante est de class <code>"nice"</code>. Elle est semblable aux listes ordinaires mais avec des puces carrées.</p> 91 <ul class="nice"> 92 <li>Les textes courants sont en Arial, Helvetica ou sans-serif. </li> 93 <li>Le code adopte la fonte Andale Mono, Courier New ou monospace.</li> 94 <li>Les liens ont des aspects différents au focus et au survol. Il faut conserver cette distinction, nécessaire à l'accessibilité et l'ergonomie.</li> 95 </ul> 96 97 <h3 id="titres">Titre h3</h3> 98 <p>Le titre de niveau h1 est réservé au titre du site-admin. Le titre de niveau h2 est réservé au breadcrumb/titre de la page courante. On utilise les titres de niveau h3 en premier niveau de titre à l'intérieur des pages, comme sur la page Import/Export.</p> 99 <p>Il ne faut pas choisir un niveau de titre en fonction de son aspect mais respecter une hiérarchie cohérente. On peut obtenir visuellement l'aspect d'un titre h3 en donnant à l'élément la class <code>"as_h3"</code>.</p> 100 <h4>Titre de niveau h4</h4> 101 <p>On peut obtenir visuellement l'aspect d'un titre h4 en donnant à l'élément la class <code>"as_h4"</code>.</p> 102 <h5>Titre de niveau h5</h5> 103 <p>Le titre de niveau h5 est assez peu employé mais son style est prévu. Dans une admin de base, on utilise les niveaux 104 h5 pour certains éléments du sidebar du billet, mais un style particulier leur est alors appliqué pour ressembler aux autres 105 items de ce sidebar.</p> 106 <div class="fieldset"> 107 <h4>Titres des encadrés</h4> 108 <p>Les titres de boîte encadrées (div de class <code>"fieldset"</code>, comme ici) se présentent comme ci-dessus.</p> 109 <p>On peut utiliser, quel que soit le niveau hx de cet intertitre la class <code>"pretty-title"</code> pour obtenir l'effet ci-dessus.</p> 110 </div> 111 <h4 class="smart-title">Autre variante</h4> 112 <p>On dispose également d'une class <code>"smart-title"</code> pour obtenir une présentation comme celle du titre de ce paragraphe.</p> 113 114 <h2>Layouts</h2> 115 116 <h3 id="onglets">Onglets</h3> 117 <p>Les descriptions des constructions en multi-colonnes ci-dessous présentent un exemple de répartition en onglets.</p> 118 <p>Chacun de ces onglets doit être défini à l'aide d'une <code><div class="multi-part"></code>. Ils seront alors automatiquement présentés sous forme d'onglets.</p> 119 120 <h3 id="multi-colonnage">Multi-colonnage</h3> 121 <div id="one-box" class="multi-part" title="One-box"> 122 <h4>Boîtes distribuées horizontalement</h4> 123 <div class="one-box"> 124 <div class="box"> 125 <p><span class="step">1</span> Toutes les boîtes de class <code>"box"</code> placées à l'intérieur d'une boîte de class <code>"one-box"</code> se distribuent horizontalement (imaginez que chaque boîte est un mot dans un paragraphe). Si les largeurs de ces boîtes ne sont pas spécifiquement définies dans la CSS, elle s'ajustent à leur contenu.</p> 126 </div> 127 <div class="box"> 128 <p><span class="step">2</span> Voici une petite boîte.</p> 129 </div> 130 <div class="box"> 131 <p><span class="step">3</span> Une autre petite boîte.</p> 132 </div> 133 <div class="box"> 134 <p><span class="step">4</span> Par défaut les « lignes » de boîtes <code>"box"</code> sont justifiées au sein de la boîte <code>"one-box"</code> et l'espacement se répartit entre elles.</p> 135 </div> 136 <div class="box"> 137 <p><span class="step">5</span> Si vous souhaitez un autre alignement des boîtes entre elles vous pouvez ajouter les class :</p> 138 <ul class="nice clear"> 139 <li><code>"txt-left"</code>,</li> 140 <li><code>"txt-right"</code></li> 141 <li>ou <code>"txt-center"</code></li> 142 </ul> 143 <p>à la class <code>"one-box"</code>.</p> 144 </div> 145 <div class="box"> 146 <p><span class="step">6</span> Le cadre placé ici autour de chaque boîte ne fait pas partie des styles par défaut.</p> 147 </div> 148 </div> 149 </div> 150 <div id="two-boxes" class="multi-part" title="Two-boxes"> 151 <h4>Boîtes distribuées deux par deux</h4> 152 <div> 153 <div class="two-boxes odd"> 154 <p><span class="step">1</span> Les boîtes de class <code>"two-boxes"</code> ont une règle CSS <code>display:inline-block;</code>. Elles se rangent alternativement à gauche et à droite. Pour plus de clarté, les blocs sont ici numérotés avec leur ordre dans le flux.</p> 155 </div><!-- 156 --><div class="two-boxes even"> 157 <p><span class="step">2</span> On peut assortir une boîte des class <code>"odd"</code> (nothing left) et <code>"even"</code> pour que les marges se placent correctement.</p> 158 </div><!-- 159 --><div class="two-boxes odd"> 160 <p><span class="step">3</span> Attention, il faut soit ne pas retourner à la ligne entre la fermeture d'une boîte <code>"two-boxes"</code> et l'ouverture de la suivante soit adopter la méthode de commentaire vide mise en place ici et expliquée chez <a href="http://www.alsacreations.com/astuce/lire/1432-display-inline-block-espaces-indesirables.html">Alsacréations</a> (« Méthode 2 »).</p> 161 </div><!-- 162 --><div class="two-boxes even"> 163 <div class="two-boxes odd"> 164 <p><span class="step">4</span> On peut bien sûr imbriquer des boîtes de class <code>"two-boxes"</code> 165 au sein d'une boîte <code>"two-boxes" afin qu'elles…</code>…</p> 166 </div><div class="two-boxes even"> 167 <p><span class="step">4 bis</span>… se distribuent horizontalement comme dans une boîte <code>"one-box"</code>.</p> 168 </div> 169 </div> 170 </div> 171 </div> 172 <div id="three-boxes" class="multi-part" title="Three-boxes"> 173 <h4>Boîtes distribuées trois par trois</h4> 174 <div> 175 <div class="three-boxes"> 176 <div class="box"> 177 <p>Sur le même principe que les « two-boxes » on peut utiliser des boîtes de class <code>"three-boxes"</code> pour répartir les contenus sur trois colonnes de 30% chacune (le reste est occupé par les marges).</p> 178 </div> 179 </div><!-- 180 --><div class="three-boxes"> 181 <div class="box"> 182 <p>Comme pour les "two-boxes" il faut soit ne pas laisser d'espace ou de retour à la ligne entre les boîtes, soit adopter la méthode recommandée plus haut.</p> 183 </div> 184 </div><!-- 185 --><div class="three-boxes"> 186 <div class="box"> 187 <p>Dans les « two-boxes » comme dans les « three-boxes », on peut placer à l'intérieur plusieurs autres div de class="box" qui s'afficheront les unes à côté des autres ou l'une en dessous de l'autre selon la place dont elles disposent.</p> 188 </div> 189 </div> 190 </div> 191 </div> 192 <div id="two-cols-50-50" class="multi-part" title="Two-cols (50/50)"> 193 <h4>Deux colonnes flottantes de largeurs égales</h4> 194 <div class="two-cols clearfix"> 195 <div class="col"> 196 <p>La div englobante porte la class <code>"two-cols"</code>, chacune de ses div porte la class <code>"col"</code>. 197 Sans autre précision les deux colonnes sont d'égale largeur.</p> 198 </div> 199 <div class="col"> 200 <p>Attention : ces colonnes sont construites avec des flottants, il faut donc penser à mettre une class <code>clear</code> à l'élément suivant ou ajouter la class <code>"clearfix"</code> à la <code>div class="two-cols"</code>.</p> 201 </div> 202 </div> 203 </div> 204 <div id="two-cols-70-30" class="multi-part" title="Two-cols (70/30)"> 205 <h4>Deux colonnes flottantes de largeurs inégales</h4> 206 <div class="two-cols clearfix"> 207 <div class="col70"> 208 <p><span class="step">col70</span> La div englobante porte la class <code>"two-cols"</code>. 209 Pour obtenir des colonnes inégales, on dispose des classes <code>"col70"</code> et <code>col30</code> à attribuer à l'une ou à l'autre de ses colonnes.</p> 210 </div> 211 <div class="col30"> 212 <p><span class="step">col30</span> Penser à mettre une class <code>"clear"</code> à l'élément suivant ou ajouter la class <code>"clearfix"</code> <code>div class="two-cols"</code>.</p> 213 </div> 214 </div> 215 </div> 216 <div id="three-cols" class="multi-part" title="Three-cols (deprecated)"> 217 <h4>Trois colonnes flottantes de largeurs égales</h4> 218 <p class="warning"><strong>Deprecated.</strong> Ces règles sont conservées dans la 2.6 par souci de rétro-compatibilité mais il est recommandé d'utiliser désormais le colonnage <a href="#three-boxes">three-boxes</a>.</p> 219 <div class="three-cols clearfix"> 220 <div class="col"> 221 <h5>Colonne 1</h5> 222 <p>La div englobante porte la class <code>"three-cols"</code>, chacune de ses div porte la class <code>"col"</code>. Les trois colonnes sont d'égale largeur.</p> 223 </div> 224 <div class="col"> 225 <h5>Colonne 2</h5> 226 <p>Voici une deuxième colonne. N'oubliez pas d'ajouter la class <code>"clearfix"</code> à la class <code>"three-cols"</code> ou un élément de class <code>"clear"</code> après cet élément.</p> 227 </div> 228 <div class="col"> 229 <h5>Colonne 3</h5> 230 <p>Voilà la troisième colonne.</p> 231 </div> 232 </div> 233 </div> 234 <hr /> 235 <p><strong>Note :</strong> dans les exemples les valeurs et les numérotations sont placées dans un <code>span class="step"</code> (et ressortent donc dans un petit bloc à fond gris).</p> 236 237 <h2>Interactions</h2> 238 239 <h3 id="elements">Éléments de formulaire</h3> 240 <form class="two-cols clearfix" action="#"> 241 <div class="col"> 242 <p><label for="ex1">Label simple + input text :</label><input id="ex1" type="text" /></p> 243 <p class="form-note">p class="form-note".</p> 244 <p><label for="ex4" class="classic">Label class="classic" + input text :</label> <input id="ex4" type="text" /></p> 245 <p><label for="ex2" class="required"><abbr title="Champ obligatoire">*</abbr> Label class="required" :</label> <input id="ex2" type="text" required placeholder="exemple" /><span class="form-note">span class="form-note"</span></p> 246 <p><label for="ex11" class="bold">Label class="bold" :</label> <input id="ex11" type="text" /></p> 247 <p class="form-note">La class="bold" est bien sûr à écrire en minuscules.</p> 248 <p><label for="ex3">Input class="maximal" :</label> <input id="ex3" type="text" class="maximal" /></p> 249 </div> 250 <div class="col"> 251 <p class="field"><label for="ex5">p.field label + input :</label><input id="ex5" type="text" /></p> 252 <p class="field"><label for="ex6">p.field label + select :</label> 253 <select id="ex6"><option value="opt2">Option 2</option><option selected="selected" value="opt2">Option 2</option></select> 254 </p> 255 <p><label class="classic" for="ex7"><input type="checkbox" checked="checked" id="ex7" value="1" name="ex7" /> 256 Checkbox (label.classic)</label></p> 257 <p><label class="classic" for="ex8-1"><input type="radio" checked="checked" id="ex8-1" value="ex8-1" name="ex8-1" /> 258 Bouton radio 1 (label.classic)</label></p> 259 <p><label class="classic" for="ex8-2"><input type="radio" id="ex8-2" value="ex8-2" name="ex8-2" /> 260 Bouton radio 2 (label.classic)</label></p> 261 <p class="form-note">Les checkboxes et les boutons radio sont dans la balise <label>.</p> 262 <p><label class="classic" for="ex9"><input type="checkbox" 263 checked="checked" id="ex9" value="1" title="intitulé du champ" /></label> <label 264 for="ex10" class="classic">checkbox.classic + label class="classic" :</label> <input id="ex10" type="text" /></p> 265 </div> 266 </form> 267 <form action="#" class="clear"> 268 <fieldset> 269 <legend>Légende de fieldset</legend> 270 <p>Attention: Les fieldsets ne doivent être utilisés que pour isoler un groupe de champs au sein d'un formulaire.</p> 271 </fieldset> 272 </form> 273 274 <h3 id="boutons">Boutons</h3> 275 <div class="clearfix"> 276 <p><a class="button add">a.button.add</a> Se place en haut à droite (dans un p.top-add)</p> 277 <p><input type="button" value="Type button" /> <a href="#" class="button">a.button</a> <input type="reset" value="Type reset" /> <a href="#" class="button reset">a.reset</a></p> 278 <p><input type="submit" value="Type submit" /> <input type="submit" class="delete" value="Type submit class delete" /> <a href="#" class="button delete">a.button delete</a></p> 279 <p><input type="submit" value="Type submit class disabled" class="disabled" /></p> 280 </div> 281 282 <h3 id="messages">Messages</h3> 283 <h4 class="smart-title">Messages système</h4> 284 <p>Il existe quatre types de messages système auxquels correspondent des classes CSS : .error, .message, .success, .warning-msg. Ils s'affichent en haut de page, sous le titre/breadcrumb.</p> 285 <div class="message"> 286 <p>Message simple. Le plus souvent horodaté dcPage::message</p> 287 </div> 288 <div class="success"> 289 <p>Message de succès. Le plus souvent horodaté dcPage::success</p> 290 </div> 291 <div class="warning-msg"> 292 <p>Message warning. Non horodaté dcPage::warning</p> 293 </div> 294 <div class="error"> 295 <p>Message d'erreur. Non horodaté dcPage::error</p> 296 </div> 297 <p>La classe .static-msg peut être utilisée directement pour affichage en haut de page :</p> 298 <div class="static-msg"> 299 <p>Comme le message simple mais sans effets de transition.</p> 300 </div> 301 <p>Un type de message réservé à Dotclear peut s'afficher en haut de la page :</p> 302 <div class="dc-update"> 303 <h3>Dotclear 42 est disponible</h3> 304 <p><a class="button submit" href="#">Mettre à jour maintenant</a> 305 <a class="button" href="u#">Me le rappeler plus tard</a></p> 306 <p class="updt-info"><a href="#">Informations sur cette version</a></p> 307 </div> 308 <h4 class="smart-title">Messages contextuels</h4> 309 <p class="warn">Paragraphe de message d'alerte class warn ou warning.</p> 310 <p class="info">Paragraphe de message de class info.</p> 311 <p>Ces messages sont en display:inline-block. Le fond s'adapte à la longueur du message.</p> 312 313 <h2>Navigation</h2> 314 315 <h3 id="direct">Selecteur d'accès direct</h3> 316 <p>Sur des pages longues et denses comme les pages about:config ou about:preferences, on peut utiliser un sélecteur pour faciliter l'accès direct aux sections.</p> 317 <p class="anchor-nav"> 318 <label class="classic" for="lp_nav">Aller à : </label> 319 <select id="lp_nav" name="lp_nav"> 320 <option value="#l_accessibility">accessibility</option> 321 <option value="#l_dashboard">dashboard</option> 322 <option value="#l_dmhostingmonitor">dmhostingmonitor</option> 323 <option value="#l_dmpending">dmpending</option> 324 <option value="#l_favorites">favorites</option> 325 <option value="#l_filters">filters</option> 326 <option value="#l_interface">interface</option> 327 <option value="#l_lists">lists</option> 328 <option value="#l_toggles">toggles</option> 329 </select> 330 <input type="submit" id="lp_submit" value="Ok" style="display: none;" /> 331 <input type="hidden" value="aboutConfig" name="p" /> 332 </p> 333 <h3 id="prevnext">Navigation contextuelle</h3> 334 <p><a title="Titre du lien" href="http://fr.dotclear.org/blog" class="onblog_link outgoing">Lien vers le blog <img alt="" src="images/outgoing-blue.png" /></a></p> 335 <p class="nav_prevnext"><a title="Titre de l'élément précédente" href="post.php?id=4145">« Élément précédent</a> | <a title="Titre de l'élément suivant" href="#">Élément suivant »</a></p> 336 337 <h3 id="pseudo-tabs">Pseudo-onglets </h3> 338 <p>Les pseudo-onglets permettent d'ajouter des sous-pages qui sont des liens vers d'autres pages, par opposition aux onglets qui sont des sections internes à la page.</p> 339 <p>Les pseudo-onglets sont à positionner immédiatement après le breadcrumb (ici un hr simule le trait sous le breadcrumb).</p> 340 <p>Ces pseudo-onglets doivent être définis avec un <code><ul class="pseudo-tabs"></code> et des <code><li></code>.</p> 341 <hr style="margin-bottom: .75em;" /> 342 <ul class="pseudo-tabs"> 343 <li><a href="#">Page 1</a></li> 344 <li><a href="#">Autre faux onglet</a></li> 345 <li><a href="#" class="active">Onglet actif</a></li> 346 <li><a href="#">Liste 4</a></li> 347 </ul> 348 349 <h2 id="common">Tableaux</h2> 350 <p>Il existe deux mises en forme type de tableaux selon que l'on cherche à faire un tableau ordinaire 351 ou un tableau dont on peut déplacer les lignes par glisser déposer (voir plus bas). Cependant certaines règles 352 sont communes à tout les tableaux.</p> 353 354 <h3>Règles communes</h3> 355 <h4>Largeur du tableau</h4> 356 <p>Sauf pour des tableaux particuliers (absents dans l'admin mais qui pourraient être nécessaires 357 à un plugin,les tableaux occupent toute la largeur de la page. Afin que les tableaux soient consultables 358 sur un mobile en navigant horizontalement, on englobe le tableau dans une <code>div class="table-outer"</code>, 359 qui servira de « conteneur ».</p> 360 <h4>Accessibilité</h4> 361 <p>Les éléments caption, th, scope sont nécessaires à l'accessibilité. Ne les oubliez pas ! ». 362 On peut utiliser la <code>class="hidden"</code> sur l'élément <code>caption</code> (qui accueille 363 le titre du tableau) si vous ne souhaitez pas qu'il soit affiché sur la page.</p> 364 <h4>Les classes</h4> 365 <p>Des classes particulières peuvent être attribuées aux lignes :</p> 366 <ul> 367 <li><code>line</code> (systématique) : pour les traits horizontaux et le fond gris léger 368 au survol ;</li> 369 <li><code>offline</code> : pour un noir estompé (gris quoi).</li> 370 </ul> 371 <p>Des classes particulières peuvent être appliquées aux cellules :</p> 372 <ul> 373 <li><code>nowrap</code> : pas de retour à la ligne dans la cellule, quelle que soit la 374 largeur de la page ;</li> 375 <li><code>maximal</code> : la cellule prendra toute la largeur restante disponible ;</li> 376 <li><code>count</code> : le contenu de la cellule sera aligné à droite avec un petit retrait.</li> 377 </ul> 378 <h3 id="courants">Tableau classique</h3> 379 <div class="table-outer"> 380 <table> 381 <caption class="hidden">Liste des entrées</caption> 382 <tr> 383 <th colspan="2" class="first">Titre</th> 384 <th scope="col">Date</th> 385 <th scope="col">Catégorie</th> 386 <th scope="col">Auteur</th> 387 <th scope="col">Commentaires</th> 388 <th scope="col">Rétroliens</th> 389 <th scope="col">État</th> 390 </tr> 391 <tr class="line"> 392 <td class="nowrap"><input type="checkbox" name="name1" value="value1" /></td> 393 <td class="maximal" scope="row"><a href="#">Mon cher Franck</a></td> 394 <td class="nowrap count">06/08/2013 19:16</td> 395 <td class="nowrap"><a href="#">Les aventures du clafoutis</a></td> 396 <td class="nowrap">kozlika</td><td class="nowrap count">4</td> 397 <td class="nowrap count">0</td><td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> <img alt="Sélectionné" title="Sélectionné" src="images/selected.png" /> </td> 398 </tr> 399 <tr class="line offline"> 400 <td class="nowrap"><input type="checkbox" name="name2" value="value2" /></td> 401 <td class="maximal" scope="row"><a href="#">Dotclear 2.3.0</a></td> 402 <td class="nowrap count">16/05/2011 22:29</td> 403 <td class="nowrap"><a href="#">Les aventures du clafoutis</a></td> 404 <td class="nowrap">kozlika</td><td class="nowrap count">5</td> 405 <td class="nowrap count">0</td><td class="nowrap status"><img alt="Non publié" title="Non publié" src="images/check-off.png" /> <img alt="Sélectionné" title="Sélectionné" src="images/selected.png" /> </td> 406 </tr> 407 <tr class="line"> 408 <td class="nowrap"><input type="checkbox" name="entries[]" value="2148" /></td> 409 <td class="maximal" scope="row"><a href="#">Causons opéra au Tamm Bara</a></td> 410 <td class="nowrap count">24/11/2009 23:10</td> 411 <td class="nowrap"><a href="#">Les aventures du clafoutis</a></td> 412 <td class="nowrap">kozlika</td> 413 <td class="nowrap count">4</td><td class="nowrap count">1</td> 414 <td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> </td> 415 </tr> 416 <tr class="line"> 417 <td class="nowrap"><input type="checkbox" name="entries[]" value="2136" /></td> 418 <td class="maximal" scope="row"><a href="#">Souffler six bougies</a></td> 419 <td class="nowrap count">14/08/2009 00:00</td><td class="nowrap"><a href="#">Les aventures du clafoutis</a></td> 420 <td class="nowrap">kozlika</td> 421 <td class="nowrap count">4</td><td class="nowrap count">2</td><td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> </td> 422 </tr> 423 <tr class="line"> 424 <td class="nowrap"><input type="checkbox" name="entries[]" value="2129" /></td> 425 <td class="maximal" scope="row"><a href="#">Dotclear et grenadine, troisième édition</a></td> 426 <td class="nowrap count">15/06/2009 07:39</td> 427 <td class="nowrap"><a href="#">Les aventures du clafoutis</a></td> 428 <td class="nowrap">kozlika</td> 429 <td class="nowrap count">9</td> 430 <td class="nowrap count">1</td> 431 <td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> </td> 432 </tr> 433 <tr class="line"> 434 <td class="nowrap"><input type="checkbox" name="entries[]" value="2111" /></td> 435 <td class="maximal" scope="row"><a href="#">L'abc dotclear est né</a></td> 436 <td class="nowrap count">19/03/2009 10:31</td><td class="nowrap"><a href="#">Les aventures du clafoutis</a></td> 437 <td class="nowrap">kozlika</td> 438 <td class="nowrap count">1</td><td class="nowrap count">0</td> 439 <td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> </td> 440 </tr> 441 </table> 442 </div> 443 444 <h3 id="dragable">Tableau avec ordonnancement</h3> 445 <p>Les tableaux permettant l'ordonnancement doivent offrir la possibilité d'effectuer le classement grâce à 446 des inputs placés en début de ligne pour que le classement soit possible même lorsque cette fonctionnalité est 447 désactivée (via les préférences utilisateurs, voire une désactivation complète du javascript dans le navigateur).</p> 448 <div class="table-outer"> 449 <table class="maximal dragable"> 450 <thead> 451 <tr> 452 <th colspan="3">Titre</th> 453 <th>Date</th> 454 <th>Auteur</th> 455 <th>Commentaires</th> 456 <th>Rétroliens</th> 457 <th>État</th> 458 </tr> 459 </thead> 460 <tbody id="pageslist"> 461 <tr class="line" id="p10899"> 462 <td class="nowrap handle minimal"> 463 <input type="text" size="2" name="order[10899]" maxlength="3" value="1" class="position" title="position de Mentions légales" /> 464 </td> 465 <td class="nowrap"> 466 <input type="checkbox" name="entries[]" value="10899" title="Sélectionner cette page" /> 467 </td> 468 <td class="maximal"><a href="#">Mentions légales</a> 469 </td> 470 <td class="nowrap">17/12/2008 07:35</td> 471 <td class="nowrap">franck</td> 472 <td class="nowrap">0</td> 473 <td class="nowrap">0</td> 474 <td class="nowrap status"> 475 <img alt="Publié" title="Publié" src="images/check-on.png" /> 476 </td> 477 </tr> 478 <tr class="line" id="p10937"> 479 <td class="nowrap handle minimal"> 480 <input type="text" size="2" name="order[10937]" maxlength="3" value="2" class="position" title="position de Page active et cachée" /> 481 </td> 482 <td class="nowrap"> 483 <input type="checkbox" name="entries[]" value="10937" title="Sélectionner cette page" /> 484 </td> 485 <td class="maximal"><a href="#">Page active et cachée</a> 486 </td> 487 <td class="nowrap">26/10/2012 11:08</td> 488 <td class="nowrap">admin</td> 489 <td class="nowrap">0</td> 490 <td class="nowrap">0</td> 491 <td class="nowrap status"> 492 <img alt="Publié" title="Publié" src="images/check-on.png" /> 493 <img alt="Masqué" title="Masqué" src="images/hidden.png" /> 494 </td> 495 </tr> 496 <tr class="line offline" id="p11047"> 497 <td class="nowrap handle minimal"> 498 <input type="text" size="2" name="order[11047]" maxlength="3" value="3" class="position" title="position de Page révisionnable" /> 499 </td> 500 <td class="nowrap"> 501 <input type="checkbox" name="entries[]" value="11047" title="Sélectionner cette page" /> 502 </td> 503 <td class="maximal"><a href="#">Page révisionnable</a> 504 </td> 505 <td class="nowrap">14/12/2012 13:26</td> 506 <td class="nowrap">admin</td> 507 <td class="nowrap">0</td> 508 <td class="nowrap">0</td> 509 <td class="nowrap status"> 510 <img alt="En attente" title="En attente" src="images/check-wrn.png" /> 511 </td> 512 </tr> 513 <tr class="line offline" id="p10939"> 514 <td class="nowrap handle minimal"> 515 <input type="text" size="2" name="order[10939]" maxlength="3" value="4" class="position" title="position de Programme" /> 516 </td> 517 <td class="nowrap"> 518 <input type="checkbox" name="entries[]" value="10939" title="Sélectionner cette page" /> 519 </td> 520 <td class="maximal"><a href="#">Programme</a> 521 </td> 522 <td class="nowrap">26/10/2020 11:23</td> 523 <td class="nowrap">admin</td> 524 <td class="nowrap">0</td> 525 <td class="nowrap">0</td> 526 <td class="nowrap status"> 527 <img alt="Programmé" title="Programmé" src="images/scheduled.png" /> 528 </td> 529 </tr> 530 <tr class="line offline" id="p10940"> 531 <td class="nowrap handle minimal"> 532 <input type="text" size="2" name="order[10940]" maxlength="3" value="5" class="position" title="position de Protégée" /> 533 </td> 534 <td class="nowrap"> 535 <input type="checkbox" name="entries[]" value="10940" title="Sélectionner cette page" /> 536 </td> 537 <td class="maximal"><a href="#">Protégée</a> 538 </td> 539 <td class="nowrap">26/10/2012 11:23</td> 540 <td class="nowrap">admin</td> 541 <td class="nowrap">0</td> 542 <td class="nowrap">0</td> 543 <td class="nowrap status"> 544 <img alt="En attente" title="En attente" src="images/check-wrn.png" /> 545 <img alt="Protégé" title="Protégé" src="images/locker.png" /> 546 </td> 547 </tr> 548 </tbody> 549 </table> 550 </div> 551 552 <h2 id="iconset">Icônes</h2> 553 <p>Les icônes utilisées dans l'administration sont présentes en deux formats 64*64px pour les grandes 554 (qui sont affichées sur le tableau de bord si la page correspondante est choisie en favori par l'utilisateur) et 555 16*16px pour les petits formats.</p> 556 <p>La plupart sont dérivées de la fonte d'icônes <a href="http://www.elegantthemes.com/blog/resources/elegant-icon-font">Elegant Font</a>. Les autres sont des images vectorielles réalisées 557 par la DC Team. Nous les avons nommées <em>Traviata</em>. La palette de couleurs utilisée est la suivante :</p> 558 <p class="txt-center"><img src="images/palette-traviata.png" alt="palette des couleurs utilisées pour les icônes" /></p> 559 <p class="txt-center">Bleu : #137bbb - Vert : #9ac123 - Rouge : #c44d58 - Bleu ciel : #a2cbe9 - Gris clair : #ececec - 560 Gris moyen : #b2b2b2 - Gris foncé : #676e78.</p> 561 </div><!-- /content --> 562 </div><!-- /main --> 563 <div id="main-menu"> 564 <ul><li class="pretty-title">Typographie 565 <ul> 566 <li><a href="#texte">Texte</a></li> 567 <li><a href="#titres">Titres hx</a></li> 568 </ul> 569 </li> 570 <li class="pretty-title">Layouts 571 <ul> 572 <li><a href="#onglets">Onglets</a></li> 573 <li><a href="#multi-colonnage">Multi-colonnage</a></li> 574 </ul> 575 </li> 576 <li class="pretty-title">Interactions 577 <ul> 578 <li><a href="#elements">Éléments de formulaire</a></li> 579 <li><a href="#boutons">Boutons</a></li> 580 <li><a href="#messages">Messages</a></li> 581 </ul> 582 </li> 583 <li class="pretty-title">Navigation 584 <ul> 585 <li><a href="#direct">Accès direct</a></li> 586 <li><a href="#prevnext">Précédent, suivant</a></li> 587 <li><a href="#pseudo-tabs">Pseudo-onglets</a></li> 588 </ul> 589 </li> 590 <li class="pretty-title">Tableaux 591 <ul> 592 <li><a href="#commons">Règles communes</a></li> 593 <li><a href="#courants">Tableaux courants</a></li> 594 <li><a href="#dragables">Tableaux ordonnancés</a></li> 595 </ul> 596 </li> 597 </ul> 598 <div class="info vertical-separator"> 599 <p>Cette page vise à présenter les règles graphiques et conventions utilisées dans les pages de l'administration 600 d'une installation Dotclear, à l'usage des contributeurs et développeurs d'extensions. Elle en est elle-même 601 une illustration. L'observation de son code source peut donc servir de complément aux descriptions.</p> 602 </div> 603 </div><!-- /main-menu --> 604 605 <div id="footer"> 606 <a href="http://dotclear.org/" title="Merci de manger des clafoutis."><img src="style/dc_logos/w-dotclear90.png" alt="Merci d'utiliser Dotclear 2.6-dev." /></a> 607 </div><!-- /footer --> 608 <!-- 609 . 610 ,;:'`':: 611 __|| 612 _____/LLLL\_ 613 \__________"| 614 ~^~^~^~^~^~^~^~^~^~ 615 --> 616 </div><!-- /wrapper --> 617 617 </body> 618 618 </html> -
admin/blog_theme.php
r3398 r3730 11 11 # -- END LICENSE BLOCK ----------------------------------------- 12 12 13 require dirname(__FILE__) .'/../inc/admin/prepend.php';13 require dirname(__FILE__) . '/../inc/admin/prepend.php'; 14 14 15 15 dcPage::check('admin'); … … 21 21 # -- Page helper -- 22 22 $list = new adminThemesList( 23 $core->themes,24 $core->blog->themes_path,25 $core->blog->settings->system->store_theme_url23 $core->themes, 24 $core->blog->themes_path, 25 $core->blog->settings->system->store_theme_url 26 26 ); 27 27 adminThemesList::$distributed_modules = explode(',', DC_DISTRIB_THEMES); … … 30 30 if (!empty($_GET['shot']) && $list->modules->moduleExists($_GET['shot'])) { 31 31 32 $f= path::real(empty($_GET['src']) ?33 $core->blog->themes_path.'/'.$_GET['shot'].'/screenshot.jpg' :34 $core->blog->themes_path.'/'.$_GET['shot'].'/'.path::clean($_GET['src'])35 );36 37 if (!file_exists($f)) {38 $f = dirname(__FILE__).'/images/noscreenshot.png';39 }40 41 http::cache(array_merge(array($f), get_included_files()));42 43 header('Content-Type: '.files::getMimeType($f));44 header('Content-Length: '.filesize($f));45 readfile($f);46 47 exit;32 $f = path::real(empty($_GET['src']) ? 33 $core->blog->themes_path . '/' . $_GET['shot'] . '/screenshot.jpg' : 34 $core->blog->themes_path . '/' . $_GET['shot'] . '/' . path::clean($_GET['src']) 35 ); 36 37 if (!file_exists($f)) { 38 $f = dirname(__FILE__) . '/images/noscreenshot.png'; 39 } 40 41 http::cache(array_merge(array($f), get_included_files())); 42 43 header('Content-Type: ' . files::getMimeType($f)); 44 header('Content-Length: ' . filesize($f)); 45 readfile($f); 46 47 exit; 48 48 } 49 49 … … 51 51 if ($list->setConfiguration($core->blog->settings->system->theme)) { 52 52 53 # Get content before page headers54 include $list->includeConfiguration();55 56 # Gather content57 $list->getConfiguration();58 59 # Display page60 dcPage::open(__('Blog appearance'),61 dcPage::jsPageTabs().62 dcPage::jsColorPicker().63 64 # --BEHAVIOR-- themesToolsHeaders65 $core->callBehavior('themesToolsHeaders', $core, true),66 67 dcPage::breadcrumb(68 array(69 html::escapeHTML($core->blog->name)=> '',70 __('Blog appearance') => $list->getURL('',false),71 '<span class="page-title">'.__('Theme configuration').'</span>' => ''72 ))73 );74 75 # Display previously gathered content76 $list->displayConfiguration();77 78 dcPage::helpBlock('core_blog_theme_conf');79 dcPage::close();80 81 # Stop reading code here82 return;53 # Get content before page headers 54 include $list->includeConfiguration(); 55 56 # Gather content 57 $list->getConfiguration(); 58 59 # Display page 60 dcPage::open(__('Blog appearance'), 61 dcPage::jsPageTabs() . 62 dcPage::jsColorPicker() . 63 64 # --BEHAVIOR-- themesToolsHeaders 65 $core->callBehavior('themesToolsHeaders', $core, true), 66 67 dcPage::breadcrumb( 68 array( 69 html::escapeHTML($core->blog->name) => '', 70 __('Blog appearance') => $list->getURL('', false), 71 '<span class="page-title">' . __('Theme configuration') . '</span>' => '' 72 )) 73 ); 74 75 # Display previously gathered content 76 $list->displayConfiguration(); 77 78 dcPage::helpBlock('core_blog_theme_conf'); 79 dcPage::close(); 80 81 # Stop reading code here 82 return; 83 83 } 84 84 85 85 # -- Execute actions -- 86 86 try { 87 $list->doActions(); 88 } 89 catch (Exception $e) { 90 $core->error->add($e->getMessage()); 87 $list->doActions(); 88 } catch (Exception $e) { 89 $core->error->add($e->getMessage()); 91 90 } 92 91 93 92 # -- Page header -- 94 93 dcPage::open(__('Themes management'), 95 dcPage::jsLoad('js/_blog_theme.js').96 dcPage::jsPageTabs().97 dcPage::jsColorPicker().98 99 # --BEHAVIOR-- themesToolsHeaders100 $core->callBehavior('themesToolsHeaders', $core, false),101 102 dcPage::breadcrumb(103 array(104 html::escapeHTML($core->blog->name)=> '',105 '<span class="page-title">'.__('Blog appearance').'</span>' => ''106 ))94 dcPage::jsLoad('js/_blog_theme.js') . 95 dcPage::jsPageTabs() . 96 dcPage::jsColorPicker() . 97 98 # --BEHAVIOR-- themesToolsHeaders 99 $core->callBehavior('themesToolsHeaders', $core, false), 100 101 dcPage::breadcrumb( 102 array( 103 html::escapeHTML($core->blog->name) => '', 104 '<span class="page-title">' . __('Blog appearance') . '</span>' => '' 105 )) 107 106 ); 108 107 … … 110 109 if ($core->auth->isSuperAdmin()) { 111 110 112 # Updated modules from repo113 $modules = $list->store->get(true);114 if (!empty($modules)) {115 echo116 '<div class="multi-part" id="update" title="'.html::escapeHTML(__('Update themes')).'">'.117 '<h3>'.html::escapeHTML(__('Update themes')).'</h3>'.118 '<p>'.sprintf(119 __('There is one theme to update available from repository.', 'There are %s themes to update available from repository.', count($modules)),120 count($modules)121 ).'</p>';122 123 $list124 ->setList('theme-update')125 ->setTab('themes')126 ->setModules($modules)127 ->displayModules(128 /*cols */array('checkbox', 'name', 'sshot', 'desc', 'author', 'version', 'current_version', 'parent'),129 /* actions */array('update', 'delete')130 );131 132 echo133 '<p class="info vertical-separator">'.sprintf(134 __("Visit %s repository, the resources center for Dotclear."),135 '<a href="http://themes.dotaddict.org/galerie-dc2/">Dotaddict</a>'136 ).137 '</p>'.138 139 '</div>';140 }111 # Updated modules from repo 112 $modules = $list->store->get(true); 113 if (!empty($modules)) { 114 echo 115 '<div class="multi-part" id="update" title="' . html::escapeHTML(__('Update themes')) . '">' . 116 '<h3>' . html::escapeHTML(__('Update themes')) . '</h3>' . 117 '<p>' . sprintf( 118 __('There is one theme to update available from repository.', 'There are %s themes to update available from repository.', count($modules)), 119 count($modules) 120 ) . '</p>'; 121 122 $list 123 ->setList('theme-update') 124 ->setTab('themes') 125 ->setModules($modules) 126 ->displayModules( 127 /*cols */array('checkbox', 'name', 'sshot', 'desc', 'author', 'version', 'current_version', 'parent'), 128 /* actions */array('update', 'delete') 129 ); 130 131 echo 132 '<p class="info vertical-separator">' . sprintf( 133 __("Visit %s repository, the resources center for Dotclear."), 134 '<a href="http://themes.dotaddict.org/galerie-dc2/">Dotaddict</a>' 135 ) . 136 '</p>' . 137 138 '</div>'; 139 } 141 140 } 142 141 … … 145 144 if (!empty($modules)) { 146 145 147 echo148 '<div class="multi-part" id="themes" title="'.__('Installed themes').'">'.149 '<h3>'.__('Installed themes').'</h3>'.150 '<p class="more-info">'.__('You can configure and manage installed themes from this list.').'</p>';151 152 $list153 ->setList('theme-activate')154 ->setTab('themes')155 ->setModules($modules)156 ->displayModules(157 /* cols */array('sshot', 'distrib', 'name', 'config', 'desc', 'author', 'version', 'parent'),158 /* actions */array('select', 'behavior', 'deactivate', 'delete')159 );160 161 echo162 '</div>';146 echo 147 '<div class="multi-part" id="themes" title="' . __('Installed themes') . '">' . 148 '<h3>' . __('Installed themes') . '</h3>' . 149 '<p class="more-info">' . __('You can configure and manage installed themes from this list.') . '</p>'; 150 151 $list 152 ->setList('theme-activate') 153 ->setTab('themes') 154 ->setModules($modules) 155 ->displayModules( 156 /* cols */array('sshot', 'distrib', 'name', 'config', 'desc', 'author', 'version', 'parent'), 157 /* actions */array('select', 'behavior', 'deactivate', 'delete') 158 ); 159 160 echo 161 '</div>'; 163 162 } 164 163 … … 167 166 if (!empty($modules)) { 168 167 169 echo170 '<div class="multi-part" id="deactivate" title="'.__('Deactivated themes').'">'.171 '<h3>'.__('Deactivated themes').'</h3>'.172 '<p class="more-info">'.__('Deactivated themes are installed but not usable. You can activate them from here.').'</p>';173 174 $list175 ->setList('theme-deactivate')176 ->setTab('themes')177 ->setModules($modules)178 ->displayModules(179 /* cols */array('name', 'distrib'),180 /* actions */array('activate', 'delete')181 );182 183 echo184 '</div>';168 echo 169 '<div class="multi-part" id="deactivate" title="' . __('Deactivated themes') . '">' . 170 '<h3>' . __('Deactivated themes') . '</h3>' . 171 '<p class="more-info">' . __('Deactivated themes are installed but not usable. You can activate them from here.') . '</p>'; 172 173 $list 174 ->setList('theme-deactivate') 175 ->setTab('themes') 176 ->setModules($modules) 177 ->displayModules( 178 /* cols */array('name', 'distrib'), 179 /* actions */array('activate', 'delete') 180 ); 181 182 echo 183 '</div>'; 185 184 } 186 185 187 186 if ($core->auth->isSuperAdmin() && $list->isWritablePath()) { 188 187 189 # New modules from repo190 $search= $list->getSearch();191 $modules = $search ? $list->store->search($search) : $list->store->get();192 193 if (!empty($search) || !empty($modules)) {194 echo195 '<div class="multi-part" id="new" title="'.__('Add themes').'">'.196 '<h3>'.__('Add themes from repository').'</h3>';197 // '<p>'.__('Search and install themes directly from repository.').'</p>';198 199 $list200 ->setList('theme-new')201 ->setTab('new')202 ->setModules($modules)203 ->displaySearch()204 ->displayIndex()205 ->displayModules(206 /* cols */array('expander', 'sshot', 'name', 'score', 'config', 'desc', 'author', 'version', 'parent', 'details', 'support'),207 /* actions */array('install'),208 /* nav limit */true209 );210 211 echo212 '<p class="info vertical-separator">'.sprintf(213 __("Visit %s repository, the resources center for Dotclear."),214 '<a href="http://themes.dotaddict.org/galerie-dc2/">Dotaddict</a>'215 ).216 '</p>'.217 218 '</div>';219 }220 221 # Add a new plugin222 echo223 '<div class="multi-part" id="addtheme" title="'.__('Install or upgrade manually').'">'.224 '<h3>'.__('Add themes from a package').'</h3>'.225 '<p class="more-info">'.__('You can install themes by uploading or downloading zip files.').'</p>';226 227 $list->displayManualForm();228 229 echo230 '</div>';188 # New modules from repo 189 $search = $list->getSearch(); 190 $modules = $search ? $list->store->search($search) : $list->store->get(); 191 192 if (!empty($search) || !empty($modules)) { 193 echo 194 '<div class="multi-part" id="new" title="' . __('Add themes') . '">' . 195 '<h3>' . __('Add themes from repository') . '</h3>'; 196 // '<p>'.__('Search and install themes directly from repository.').'</p>'; 197 198 $list 199 ->setList('theme-new') 200 ->setTab('new') 201 ->setModules($modules) 202 ->displaySearch() 203 ->displayIndex() 204 ->displayModules( 205 /* cols */array('expander', 'sshot', 'name', 'score', 'config', 'desc', 'author', 'version', 'parent', 'details', 'support'), 206 /* actions */array('install'), 207 /* nav limit */true 208 ); 209 210 echo 211 '<p class="info vertical-separator">' . sprintf( 212 __("Visit %s repository, the resources center for Dotclear."), 213 '<a href="http://themes.dotaddict.org/galerie-dc2/">Dotaddict</a>' 214 ) . 215 '</p>' . 216 217 '</div>'; 218 } 219 220 # Add a new plugin 221 echo 222 '<div class="multi-part" id="addtheme" title="' . __('Install or upgrade manually') . '">' . 223 '<h3>' . __('Add themes from a package') . '</h3>' . 224 '<p class="more-info">' . __('You can install themes by uploading or downloading zip files.') . '</p>'; 225 226 $list->displayManualForm(); 227 228 echo 229 '</div>'; 231 230 } 232 231 … … 236 235 # -- Notice for super admin -- 237 236 if ($core->auth->isSuperAdmin() && !$list->isWritablePath()) { 238 echo239 '<p class="warning">'.__('Some functions are disabled, please give write access to your themes directory to enable them.').'</p>';237 echo 238 '<p class="warning">' . __('Some functions are disabled, please give write access to your themes directory to enable them.') . '</p>'; 240 239 } 241 240 -
admin/category.php
r3725 r3730 189 189 'extra_html' => 'required placeholder="' . __('Name') . '"' 190 190 )) . 191 '</p>';191 '</p>'; 192 192 if (!$cat_id) { 193 193 $rs = $core->blog->getCategories(); -
admin/comments_actions.php
r3403 r3730 11 11 # -- END LICENSE BLOCK ----------------------------------------- 12 12 13 /* ### THIS FILE IS DEPRECATED ### */13 /* ### THIS FILE IS DEPRECATED ### */ 14 14 /* ### IT IS ONLY USED FOR PLUGINS COMPATIBILITY ### */ 15 15 16 require dirname(__FILE__) .'/../inc/admin/prepend.php';16 require dirname(__FILE__) . '/../inc/admin/prepend.php'; 17 17 18 18 dcPage::check('usage,contentadmin'); 19 19 20 20 if (isset($_REQUEST['redir'])) { 21 $u = explode('?',$_REQUEST['redir']);22 $uri = $u[0];23 if (isset($u[1])) {24 parse_str($u[1],$args);25 }26 $args['redir'] = $_REQUEST['redir'];21 $u = explode('?', $_REQUEST['redir']); 22 $uri = $u[0]; 23 if (isset($u[1])) { 24 parse_str($u[1], $args); 25 } 26 $args['redir'] = $_REQUEST['redir']; 27 27 } else { 28 $uri= $core->adminurl->get("admin.comments");29 $args=array();28 $uri = $core->adminurl->get("admin.comments"); 29 $args = array(); 30 30 } 31 31 32 $comments_actions_page = new dcCommentsActionsPage($core, $uri,$args);32 $comments_actions_page = new dcCommentsActionsPage($core, $uri, $args); 33 33 $comments_actions_page->setEnableRedirSelection(false); 34 34 $comments_actions_page->process(); -
admin/csp_report.php
r3482 r3730 8 8 header('X-Content-Type-Options: "nosniff"'); 9 9 10 require dirname(__FILE__) .'/../inc/admin/prepend.php';10 require dirname(__FILE__) . '/../inc/admin/prepend.php'; 11 11 12 12 // Specify admin CSP log file if necessary 13 13 if (!defined('LOGFILE')) { 14 define('LOGFILE',path::real(DC_VAR).'/csp/csp_report.json');14 define('LOGFILE', path::real(DC_VAR) . '/csp/csp_report.json'); 15 15 } 16 16 … … 20 20 // Only continue if it’s valid JSON that is not just `null`, `0`, `false` or an 21 21 // empty string, i.e. if it could be a CSP violation report. 22 if ($data = json_decode($data, true)) {22 if ($data = json_decode($data, true)) { 23 23 24 // get source-file and blocked-URI to perform some tests25 $source_file= isset($data['csp-report']['source-file']) ? $data['csp-report']['source-file'] : '';26 $line_number= isset($data['csp-report']['line-number']) ? $data['csp-report']['line-number'] : '';27 $blocked_uri= isset($data['csp-report']['blocked-uri']) ? $data['csp-report']['blocked-uri'] : '';28 $document_uri= isset($data['csp-report']['document-uri']) ? $data['csp-report']['document-uri'] : '';29 $violated_directive = isset($data['csp-report']['violated-directive']) ? $data['csp-report']['violated-directive'] : '';24 // get source-file and blocked-URI to perform some tests 25 $source_file = isset($data['csp-report']['source-file']) ? $data['csp-report']['source-file'] : ''; 26 $line_number = isset($data['csp-report']['line-number']) ? $data['csp-report']['line-number'] : ''; 27 $blocked_uri = isset($data['csp-report']['blocked-uri']) ? $data['csp-report']['blocked-uri'] : ''; 28 $document_uri = isset($data['csp-report']['document-uri']) ? $data['csp-report']['document-uri'] : ''; 29 $violated_directive = isset($data['csp-report']['violated-directive']) ? $data['csp-report']['violated-directive'] : ''; 30 30 31 if (32 // avoid false positives notifications coming from Chrome extensions (Wappalyzer, MuteTab, etc.)33 // bug here https://code.google.com/p/chromium/issues/detail?id=52435634 strpos($source_file, 'chrome-extension://') === false31 if ( 32 // avoid false positives notifications coming from Chrome extensions (Wappalyzer, MuteTab, etc.) 33 // bug here https://code.google.com/p/chromium/issues/detail?id=524356 34 strpos($source_file, 'chrome-extension://') === false 35 35 36 // avoid false positives notifications coming from Safari extensions (diigo, evernote, etc.)37 && strpos($source_file, 'safari-extension://') === false38 && strpos($blocked_uri, 'safari-extension://') === false36 // avoid false positives notifications coming from Safari extensions (diigo, evernote, etc.) 37 && strpos($source_file, 'safari-extension://') === false 38 && strpos($blocked_uri, 'safari-extension://') === false 39 39 40 // search engine extensions ?41 && strpos($source_file, 'se-extension://') === false40 // search engine extensions ? 41 && strpos($source_file, 'se-extension://') === false 42 42 43 // added by browsers in webviews44 && strpos($blocked_uri, 'webviewprogressproxy://') === false43 // added by browsers in webviews 44 && strpos($blocked_uri, 'webviewprogressproxy://') === false 45 45 46 // Google Search App see for details https://github.com/nico3333fr/CSP-useful/commit/ecc8f9b0b379ae643bc754d2db33c8b47e185fd147 && strpos($blocked_uri, 'gsa://onpageload') === false46 // Google Search App see for details https://github.com/nico3333fr/CSP-useful/commit/ecc8f9b0b379ae643bc754d2db33c8b47e185fd1 47 && strpos($blocked_uri, 'gsa://onpageload') === false 48 48 49 ) {50 // Prepare report data (hash => info)51 $hash = hash('md5',$blocked_uri.$document_uri.$source_file.$line_number.$violated_directive);49 ) { 50 // Prepare report data (hash => info) 51 $hash = hash('md5', $blocked_uri . $document_uri . $source_file . $line_number . $violated_directive); 52 52 53 try {54 // Check report dir (create it if necessary)55 files::makeDir(dirname(LOGFILE),true);53 try { 54 // Check report dir (create it if necessary) 55 files::makeDir(dirname(LOGFILE), true); 56 56 57 // Check if report is not already stored in log file58 $contents = '';59 if (file_exists(LOGFILE)) {60 $contents = file_get_contents(LOGFILE);61 if ($contents && $contents != '') {62 if (substr($contents,-1) == ',') {63 // Remove final comma if present64 $contents = substr($contents,0,-1);65 }66 if ($contents != '') {67 $list = json_decode('['.$contents.']',true);68 if (is_array($list)) {69 foreach ($list as $idx => $value) {70 if (isset($value['hash']) && $value['hash'] == $hash) {71 // Already stored, ignore72 return;73 }74 }75 }76 }77 }78 }57 // Check if report is not already stored in log file 58 $contents = ''; 59 if (file_exists(LOGFILE)) { 60 $contents = file_get_contents(LOGFILE); 61 if ($contents && $contents != '') { 62 if (substr($contents, -1) == ',') { 63 // Remove final comma if present 64 $contents = substr($contents, 0, -1); 65 } 66 if ($contents != '') { 67 $list = json_decode('[' . $contents . ']', true); 68 if (is_array($list)) { 69 foreach ($list as $idx => $value) { 70 if (isset($value['hash']) && $value['hash'] == $hash) { 71 // Already stored, ignore 72 return; 73 } 74 } 75 } 76 } 77 } 78 } 79 79 80 // Add report to the file81 if (!($fp = @fopen(LOGFILE,'a'))) {82 // Unable to open file, ignore83 return;84 }80 // Add report to the file 81 if (!($fp = @fopen(LOGFILE, 'a'))) { 82 // Unable to open file, ignore 83 return; 84 } 85 85 86 // Prettify the JSON-formatted data87 $violation = array_merge(array('hash' => $hash),$data['csp-report']);88 $output = json_encode($violation,JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);86 // Prettify the JSON-formatted data 87 $violation = array_merge(array('hash' => $hash), $data['csp-report']); 88 $output = json_encode($violation, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); 89 89 90 // The file content will have to be enclosed in brackets [] before91 // beeing decoded with json_decoded(<content>,true);92 fprintf($fp,($contents != '' ? ',' : '').'%s',$output);90 // The file content will have to be enclosed in brackets [] before 91 // beeing decoded with json_decoded(<content>,true); 92 fprintf($fp, ($contents != '' ? ',' : '') . '%s', $output); 93 93 94 }catch (Exception $e) {95 return;96 }97 }94 } catch (Exception $e) { 95 return; 96 } 97 } 98 98 } -
admin/help.php
r3647 r3730 11 11 # -- END LICENSE BLOCK ----------------------------------------- 12 12 13 require dirname(__FILE__) .'/../inc/admin/prepend.php';13 require dirname(__FILE__) . '/../inc/admin/prepend.php'; 14 14 15 15 dcPage::check('usage,contentadmin'); 16 16 17 $helpPage = function() 18 { 19 $ret = array('content' => '', 'title' => ''); 17 $helpPage = function () { 18 $ret = array('content' => '', 'title' => ''); 20 19 21 $args = func_get_args(); 22 if (empty($args)) { 23 return $ret; 24 }; 20 $args = func_get_args(); 21 if (empty($args)) { 22 return $ret; 23 } 24 ; 25 25 26 global $__resources;27 if (empty($__resources['help'])) {28 return $ret;29 }26 global $__resources; 27 if (empty($__resources['help'])) { 28 return $ret; 29 } 30 30 31 $content = ''; 32 $title = ''; 33 foreach ($args as $v) 34 { 35 if (is_object($v) && isset($v->content)) { 36 $content .= $v->content; 37 continue; 38 } 31 $content = ''; 32 $title = ''; 33 foreach ($args as $v) { 34 if (is_object($v) && isset($v->content)) { 35 $content .= $v->content; 36 continue; 37 } 39 38 40 if (!isset($__resources['help'][$v])) {41 continue;42 }43 $f = $__resources['help'][$v];44 if (!file_exists($f) || !is_readable($f)) {45 continue;46 }39 if (!isset($__resources['help'][$v])) { 40 continue; 41 } 42 $f = $__resources['help'][$v]; 43 if (!file_exists($f) || !is_readable($f)) { 44 continue; 45 } 47 46 48 $fc = file_get_contents($f);49 if (preg_match('|<body[^>]*?>(.*?)</body>|ms',$fc,$matches)) {50 $content .= $matches[1];51 if (preg_match('|<title[^>]*?>(.*?)</title>|ms',$fc,$matches)) {52 $title = $matches[1];53 }54 } else {55 $content .= $fc;56 }57 }47 $fc = file_get_contents($f); 48 if (preg_match('|<body[^>]*?>(.*?)</body>|ms', $fc, $matches)) { 49 $content .= $matches[1]; 50 if (preg_match('|<title[^>]*?>(.*?)</title>|ms', $fc, $matches)) { 51 $title = $matches[1]; 52 } 53 } else { 54 $content .= $fc; 55 } 56 } 58 57 59 if (trim($content) == '') {60 return $ret;61 }58 if (trim($content) == '') { 59 return $ret; 60 } 62 61 63 $ret['content'] = $content;64 if ($title != '') {65 $ret['title'] = $title;66 }67 return $ret;62 $ret['content'] = $content; 63 if ($title != '') { 64 $ret['title'] = $title; 65 } 66 return $ret; 68 67 }; 69 68 70 $help_page = !empty($_GET['page']) ? html::escapeHTML($_GET['page']) : 'index';69 $help_page = !empty($_GET['page']) ? html::escapeHTML($_GET['page']) : 'index'; 71 70 $content_array = $helpPage($help_page); 72 71 if (($content_array['content'] == '') || ($help_page == 'index')) { 73 $content_array = $helpPage('index');72 $content_array = $helpPage('index'); 74 73 } 75 74 if ($content_array['title'] != '') { 76 $breadcrumb = dcPage::breadcrumb(77 array(78 __('Global help')=> $core->adminurl->get("admin.help"),79 $content_array['title'] => ''80 ));75 $breadcrumb = dcPage::breadcrumb( 76 array( 77 __('Global help') => $core->adminurl->get("admin.help"), 78 $content_array['title'] => '' 79 )); 81 80 } else { 82 $breadcrumb = dcPage::breadcrumb(83 array(84 __('Global help') => ''85 ));81 $breadcrumb = dcPage::breadcrumb( 82 array( 83 __('Global help') => '' 84 )); 86 85 } 87 86 … … 89 88 -------------------------------------------------------- */ 90 89 dcPage::open(__('Global help'), 91 dcPage::jsPageTabs('first-step'),92 $breadcrumb90 dcPage::jsPageTabs('first-step'), 91 $breadcrumb 93 92 ); 94 93 -
admin/index.php
r3725 r3730 320 320 form::hidden('post_lang', $core->auth->getInfo('user_lang')) . 321 321 form::hidden('post_notes', '') . 322 '</p>' . 323 '</form>' . 322 '</p>' . 323 '</form>' . 324 '</div>'; 325 } 326 } 327 328 if ($dashboardContents != '' || $dashboardItems != '') { 329 echo 330 '<div id="dashboard-boxes">' . 331 ($dashboardItems != '' ? '<div class="db-items">' . $dashboardItems . '</div>' : '') . 332 ($dashboardContents != '' ? '<div class="db-contents">' . $dashboardContents . '</div>' : '') . 324 333 '</div>'; 325 } 326 } 327 328 if ($dashboardContents != '' || $dashboardItems != '') { 329 echo 330 '<div id="dashboard-boxes">' . 331 ($dashboardItems != '' ? '<div class="db-items">' . $dashboardItems . '</div>' : '') . 332 ($dashboardContents != '' ? '<div class="db-contents">' . $dashboardContents . '</div>' : '') . 333 '</div>'; 334 } 335 336 echo '</div>'; #end dashboard-main 337 dcPage::helpBlock('core_dashboard'); 338 dcPage::close(); 334 } 335 336 echo '</div>'; #end dashboard-main 337 dcPage::helpBlock('core_dashboard'); 338 dcPage::close(); -
admin/install/check.php
r3626 r3730 10 10 # 11 11 # -- END LICENSE BLOCK ----------------------------------------- 12 if (!defined('DC_RC_PATH')) { return;}12 if (!defined('DC_RC_PATH')) {return;} 13 13 14 function dcSystemCheck($con, &$err)14 function dcSystemCheck($con, &$err) 15 15 { 16 $err = array();16 $err = array(); 17 17 18 if (version_compare(phpversion(),'5.5','<')) {19 $err[] = sprintf(__('PHP version is %s (5.5 or earlier needed).'),phpversion());20 }18 if (version_compare(phpversion(), '5.5', '<')) { 19 $err[] = sprintf(__('PHP version is %s (5.5 or earlier needed).'), phpversion()); 20 } 21 21 22 if (!function_exists('mb_detect_encoding')) {23 $err[] = __('Multibyte string module (mbstring) is not available.');24 }22 if (!function_exists('mb_detect_encoding')) { 23 $err[] = __('Multibyte string module (mbstring) is not available.'); 24 } 25 25 26 if (!function_exists('iconv')) {27 $err[] = __('Iconv module is not available.');28 }26 if (!function_exists('iconv')) { 27 $err[] = __('Iconv module is not available.'); 28 } 29 29 30 if (!function_exists('ob_start')) {31 $err[] = __('Output control functions are not available.');32 }30 if (!function_exists('ob_start')) { 31 $err[] = __('Output control functions are not available.'); 32 } 33 33 34 if (!function_exists('simplexml_load_string')) {35 $err[] = __('SimpleXML module is not available.');36 }34 if (!function_exists('simplexml_load_string')) { 35 $err[] = __('SimpleXML module is not available.'); 36 } 37 37 38 if (!function_exists('dom_import_simplexml')) {39 $err[] = __('DOM XML module is not available.');40 }38 if (!function_exists('dom_import_simplexml')) { 39 $err[] = __('DOM XML module is not available.'); 40 } 41 41 42 $pcre_str = base64_decode('w6nDqMOgw6o=');43 if (!@preg_match('/'.$pcre_str.'/u', $pcre_str)) {44 $err[] = __('PCRE engine does not support UTF-8 strings.');45 }42 $pcre_str = base64_decode('w6nDqMOgw6o='); 43 if (!@preg_match('/' . $pcre_str . '/u', $pcre_str)) { 44 $err[] = __('PCRE engine does not support UTF-8 strings.'); 45 } 46 46 47 if (!function_exists("spl_classes")) {48 $err[] = __('SPL module is not available.');49 }47 if (!function_exists("spl_classes")) { 48 $err[] = __('SPL module is not available.'); 49 } 50 50 51 if ($con->driver() == 'mysql' || $con->driver() == 'mysqli' || $con->driver() == 'mysqlimb4') 52 { 53 if (version_compare($con->version(),'4.1','<')) 54 { 55 $err[] = sprintf(__('MySQL version is %s (4.1 or earlier needed).'),$con->version()); 56 } 57 else 58 { 59 $rs = $con->select('SHOW ENGINES'); 60 $innodb = false; 61 while ($rs->fetch()) { 62 if (strtolower($rs->f(0)) == 'innodb' && strtolower($rs->f(1)) != 'disabled' && strtolower($rs->f(1)) != 'no') { 63 $innodb = true; 64 break; 65 } 66 } 51 if ($con->driver() == 'mysql' || $con->driver() == 'mysqli' || $con->driver() == 'mysqlimb4') { 52 if (version_compare($con->version(), '4.1', '<')) { 53 $err[] = sprintf(__('MySQL version is %s (4.1 or earlier needed).'), $con->version()); 54 } else { 55 $rs = $con->select('SHOW ENGINES'); 56 $innodb = false; 57 while ($rs->fetch()) { 58 if (strtolower($rs->f(0)) == 'innodb' && strtolower($rs->f(1)) != 'disabled' && strtolower($rs->f(1)) != 'no') { 59 $innodb = true; 60 break; 61 } 62 } 67 63 68 if (!$innodb) { 69 $err[] = __('MySQL InnoDB engine is not available.'); 70 } 71 } 72 } 73 elseif ($con->driver() == 'pgsql') 74 { 75 if (version_compare($con->version(),'8.0','<')) 76 { 77 $err[] = sprintf(__('PostgreSQL version is %s (8.0 or earlier needed).'),$con->version()); 78 } 79 } 64 if (!$innodb) { 65 $err[] = __('MySQL InnoDB engine is not available.'); 66 } 67 } 68 } elseif ($con->driver() == 'pgsql') { 69 if (version_compare($con->version(), '8.0', '<')) { 70 $err[] = sprintf(__('PostgreSQL version is %s (8.0 or earlier needed).'), $con->version()); 71 } 72 } 80 73 81 return count($err) == 0;74 return count($err) == 0; 82 75 } -
admin/media_item.php
r3725 r3730 767 767 768 768 form::datetime('media_dt', array('default' => html::escapeHTML(dt::str('%Y-%m-%dT%H:%M', $file->media_dt)))) . 769 */769 */ 770 770 '</p>' . 771 771 '<p><label for="media_private" class="classic">' . form::checkbox('media_private', 1, $file->media_priv) . ' ' . -
admin/plugin.php
r3333 r3730 11 11 # -- END LICENSE BLOCK ----------------------------------------- 12 12 13 require dirname(__FILE__) .'/../inc/admin/prepend.php';13 require dirname(__FILE__) . '/../inc/admin/prepend.php'; 14 14 15 15 dcPage::check('usage,contentadmin'); 16 16 17 17 $p_file = ''; 18 $p = !empty($_REQUEST['p']) ? $_REQUEST['p'] : null;19 $popup = (integer) !empty($_REQUEST['popup']);18 $p = !empty($_REQUEST['p']) ? $_REQUEST['p'] : null; 19 $popup = (integer) !empty($_REQUEST['popup']); 20 20 21 21 if ($popup) { 22 $open_f = array('dcPage','openPopup');23 $close_f = array('dcPage','closePopup');22 $open_f = array('dcPage', 'openPopup'); 23 $close_f = array('dcPage', 'closePopup'); 24 24 } else { 25 $open_f = array('dcPage','open');26 $close_f = array('dcPage','close');25 $open_f = array('dcPage', 'open'); 26 $close_f = array('dcPage', 'close'); 27 27 } 28 28 29 29 if ($core->plugins->moduleExists($p)) { 30 $p_file = $core->plugins->moduleRoot($p).'/index.php';30 $p_file = $core->plugins->moduleRoot($p) . '/index.php'; 31 31 } 32 32 33 if (file_exists($p_file)) 34 { 35 # Loading plugin 36 $p_info = $core->plugins->getModules($p); 33 if (file_exists($p_file)) { 34 # Loading plugin 35 $p_info = $core->plugins->getModules($p); 37 36 38 $p_name = $p;39 $p_url = 'plugin.php?p='.$p;37 $p_name = $p; 38 $p_url = 'plugin.php?p=' . $p; 40 39 41 $p_title= 'no content - plugin';42 $p_head= '';43 $p_content = '<p>'.__('No content found on this plugin.').'</p>';40 $p_title = 'no content - plugin'; 41 $p_head = ''; 42 $p_content = '<p>' . __('No content found on this plugin.') . '</p>'; 44 43 45 ob_start();46 include $p_file;47 $res = ob_get_contents();48 ob_end_clean();44 ob_start(); 45 include $p_file; 46 $res = ob_get_contents(); 47 ob_end_clean(); 49 48 50 if (preg_match('|<head>(.*?)</head|ms',$res,$m)) {51 if (preg_match('|<title>(.*?)</title>|ms',$m[1],$mt)) {52 $p_title = $mt[1];53 }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 } 54 53 55 if (preg_match_all('|(<script.*?>.*?</script>)|ms',$m[1],$ms)) {56 foreach ($ms[1] as $v) {57 $p_head .= $v."\n";58 }59 }54 if (preg_match_all('|(<script.*?>.*?</script>)|ms', $m[1], $ms)) { 55 foreach ($ms[1] as $v) { 56 $p_head .= $v . "\n"; 57 } 58 } 60 59 61 if (preg_match_all('|(<style.*?>.*?</style>)|ms',$m[1],$ms)) {62 foreach ($ms[1] as $v) {63 $p_head .= $v."\n";64 }65 }60 if (preg_match_all('|(<style.*?>.*?</style>)|ms', $m[1], $ms)) { 61 foreach ($ms[1] as $v) { 62 $p_head .= $v . "\n"; 63 } 64 } 66 65 67 if (preg_match_all('|(<link.*?/>)|ms',$m[1],$ms)) {68 foreach ($ms[1] as $v) {69 $p_head .= $v."\n";70 }71 }72 }66 if (preg_match_all('|(<link.*?/>)|ms', $m[1], $ms)) { 67 foreach ($ms[1] as $v) { 68 $p_head .= $v . "\n"; 69 } 70 } 71 } 73 72 74 if (preg_match('|<body.*?>(.+)</body>|ms',$res,$m)) {75 $p_content = $m[1];76 }73 if (preg_match('|<body.*?>(.+)</body>|ms', $res, $m)) { 74 $p_content = $m[1]; 75 } 77 76 78 call_user_func($open_f,$p_title,$p_head); 79 echo $p_content; 80 if (!$popup) { 81 // Add direct links to plugin settings if any 82 $settings = adminModulesList::getSettingsUrls($core,$p,true,false); 83 if (!empty($settings)) { 84 echo '<hr class="clear"/><p class="right modules">'.implode(' - ',$settings).'</p>'; 85 } 86 } 87 call_user_func($close_f); 77 call_user_func($open_f, $p_title, $p_head); 78 echo $p_content; 79 if (!$popup) { 80 // Add direct links to plugin settings if any 81 $settings = adminModulesList::getSettingsUrls($core, $p, true, false); 82 if (!empty($settings)) { 83 echo '<hr class="clear"/><p class="right modules">' . implode(' - ', $settings) . '</p>'; 84 } 85 } 86 call_user_func($close_f); 87 } else { 88 call_user_func($open_f, __('Plugin not found'), '', 89 dcPage::breadcrumb( 90 array( 91 __('System') => '', 92 __('Plugin not found') => '' 93 )) 94 ); 95 96 echo '<p>' . __('The plugin you reached does not exist or does not have an admin page.') . '</p>'; 97 98 call_user_func($close_f); 88 99 } 89 else90 {91 call_user_func($open_f,__('Plugin not found'),'',92 dcPage::breadcrumb(93 array(94 __('System') => '',95 __('Plugin not found') => ''96 ))97 );98 99 echo '<p>'.__('The plugin you reached does not exist or does not have an admin page.').'</p>';100 101 call_user_func($close_f);102 } -
admin/plugins.php
r3398 r3730 11 11 # -- END LICENSE BLOCK ----------------------------------------- 12 12 13 require dirname(__FILE__) .'/../inc/admin/prepend.php';13 require dirname(__FILE__) . '/../inc/admin/prepend.php'; 14 14 15 15 dcPage::check('admin'); … … 17 17 # -- Page helper -- 18 18 $list = new adminModulesList( 19 $core->plugins,20 DC_PLUGINS_ROOT,21 $core->blog->settings->system->store_plugin_url19 $core->plugins, 20 DC_PLUGINS_ROOT, 21 $core->blog->settings->system->store_plugin_url 22 22 ); 23 23 … … 25 25 adminModulesList::$distributed_modules = explode(',', DC_DISTRIB_PLUGINS); 26 26 27 if ($core->plugins->disableDepModules($core->adminurl->get('admin.plugins', array()))) {28 exit;27 if ($core->plugins->disableDepModules($core->adminurl->get('admin.plugins', array()))) { 28 exit; 29 29 } 30 30 … … 32 32 if ($list->setConfiguration()) { 33 33 34 # Get content before page headers35 include $list->includeConfiguration();36 37 # Gather content38 $list->getConfiguration();39 40 # Display page41 dcPage::open(__('Plugins management'),42 43 # --BEHAVIOR-- pluginsToolsHeaders44 $core->callBehavior('pluginsToolsHeaders', $core, true),45 46 dcPage::breadcrumb(47 array(48 html::escapeHTML($core->blog->name)=> '',49 __('Plugins management') => $list->getURL('',false),50 '<span class="page-title">'.__('Plugin configuration').'</span>' => ''51 ))52 );53 54 # Display previously gathered content55 $list->displayConfiguration();56 57 dcPage::helpBlock('core_plugins_conf');58 dcPage::close();59 60 # Stop reading code here61 return;34 # Get content before page headers 35 include $list->includeConfiguration(); 36 37 # Gather content 38 $list->getConfiguration(); 39 40 # Display page 41 dcPage::open(__('Plugins management'), 42 43 # --BEHAVIOR-- pluginsToolsHeaders 44 $core->callBehavior('pluginsToolsHeaders', $core, true), 45 46 dcPage::breadcrumb( 47 array( 48 html::escapeHTML($core->blog->name) => '', 49 __('Plugins management') => $list->getURL('', false), 50 '<span class="page-title">' . __('Plugin configuration') . '</span>' => '' 51 )) 52 ); 53 54 # Display previously gathered content 55 $list->displayConfiguration(); 56 57 dcPage::helpBlock('core_plugins_conf'); 58 dcPage::close(); 59 60 # Stop reading code here 61 return; 62 62 } 63 63 64 64 # -- Execute actions -- 65 65 try { 66 $list->doActions(); 67 } 68 catch (Exception $e) { 69 $core->error->add($e->getMessage()); 66 $list->doActions(); 67 } catch (Exception $e) { 68 $core->error->add($e->getMessage()); 70 69 } 71 70 … … 73 72 $plugins_install = null; 74 73 if (!$core->error->flag()) { 75 $plugins_install = $core->plugins->installModules();74 $plugins_install = $core->plugins->installModules(); 76 75 } 77 76 78 77 # -- Page header -- 79 78 dcPage::open(__('Plugins management'), 80 dcPage::jsLoad('js/_plugins.js').81 dcPage::jsPageTabs().82 83 # --BEHAVIOR-- pluginsToolsHeaders84 $core->callBehavior('pluginsToolsHeaders', $core, false),85 86 dcPage::breadcrumb(87 array(88 __('System')=> '',89 __('Plugins management') => ''90 ))79 dcPage::jsLoad('js/_plugins.js') . 80 dcPage::jsPageTabs() . 81 82 # --BEHAVIOR-- pluginsToolsHeaders 83 $core->callBehavior('pluginsToolsHeaders', $core, false), 84 85 dcPage::breadcrumb( 86 array( 87 __('System') => '', 88 __('Plugins management') => '' 89 )) 91 90 ); 92 91 93 92 # -- Plugins install messages -- 94 93 if (!empty($plugins_install['success'])) { 95 echo96 '<div class="static-msg">'.__('Following plugins have been installed:').'<ul>';97 98 foreach ($plugins_install['success'] as $k => $v) {99 echo100 '<li>'.$k.'</li>';101 }102 103 echo104 '</ul></div>';94 echo 95 '<div class="static-msg">' . __('Following plugins have been installed:') . '<ul>'; 96 97 foreach ($plugins_install['success'] as $k => $v) { 98 echo 99 '<li>' . $k . '</li>'; 100 } 101 102 echo 103 '</ul></div>'; 105 104 } 106 105 if (!empty($plugins_install['failure'])) { 107 echo108 '<div class="error">'.__('Following plugins have not been installed:').'<ul>';109 110 foreach ($plugins_install['failure'] as $k => $v) {111 echo112 '<li>'.$k.' ('.$v.')</li>';113 }114 115 echo116 '</ul></div>';106 echo 107 '<div class="error">' . __('Following plugins have not been installed:') . '<ul>'; 108 109 foreach ($plugins_install['failure'] as $k => $v) { 110 echo 111 '<li>' . $k . ' (' . $v . ')</li>'; 112 } 113 114 echo 115 '</ul></div>'; 117 116 } 118 117 … … 120 119 if ($core->auth->isSuperAdmin()) { 121 120 122 # Updated modules from repo123 $modules = $list->store->get(true);124 if (!empty($modules)) {125 echo126 '<div class="multi-part" id="update" title="'.html::escapeHTML(__('Update plugins')).'">'.127 '<h3>'.html::escapeHTML(__('Update plugins')).'</h3>'.128 '<p>'.sprintf(129 __('There is one plugin to update available from repository.', 'There are %s plugins to update available from repository.', count($modules)),130 count($modules)131 ).'</p>';132 133 $list134 ->setList('plugin-update')135 ->setTab('update')136 ->setModules($modules)137 ->displayModules(138 /*cols */array('checkbox', 'icon', 'name', 'version', 'current_version', 'desc'),139 /* actions */array('update')140 );141 142 echo143 '<p class="info vertical-separator">'.sprintf(144 __("Visit %s repository, the resources center for Dotclear."),145 '<a href="http://plugins.dotaddict.org/dc2/">Dotaddict</a>'146 ).147 '</p>'.148 149 '</div>';150 }121 # Updated modules from repo 122 $modules = $list->store->get(true); 123 if (!empty($modules)) { 124 echo 125 '<div class="multi-part" id="update" title="' . html::escapeHTML(__('Update plugins')) . '">' . 126 '<h3>' . html::escapeHTML(__('Update plugins')) . '</h3>' . 127 '<p>' . sprintf( 128 __('There is one plugin to update available from repository.', 'There are %s plugins to update available from repository.', count($modules)), 129 count($modules) 130 ) . '</p>'; 131 132 $list 133 ->setList('plugin-update') 134 ->setTab('update') 135 ->setModules($modules) 136 ->displayModules( 137 /*cols */array('checkbox', 'icon', 'name', 'version', 'current_version', 'desc'), 138 /* actions */array('update') 139 ); 140 141 echo 142 '<p class="info vertical-separator">' . sprintf( 143 __("Visit %s repository, the resources center for Dotclear."), 144 '<a href="http://plugins.dotaddict.org/dc2/">Dotaddict</a>' 145 ) . 146 '</p>' . 147 148 '</div>'; 149 } 151 150 } 152 151 153 152 echo 154 '<div class="multi-part" id="plugins" title="' .__('Installed plugins').'">';153 '<div class="multi-part" id="plugins" title="' . __('Installed plugins') . '">'; 155 154 156 155 # Activated modules … … 158 157 if (!empty($modules)) { 159 158 160 echo161 '<h3>'.($core->auth->isSuperAdmin() ?__('Activated plugins') : __('Installed plugins')).'</h3>'.162 '<p class="more-info">'.__('You can configure and manage installed plugins from this list.').'</p>';163 164 $list165 ->setList('plugin-activate')166 ->setTab('plugins')167 ->setModules($modules)168 ->displayModules(169 /* cols */ array('expander', 'icon', 'name', 'version', 'desc', 'distrib','deps'),170 /* actions */array('deactivate', 'delete', 'behavior')171 );159 echo 160 '<h3>' . ($core->auth->isSuperAdmin() ? __('Activated plugins') : __('Installed plugins')) . '</h3>' . 161 '<p class="more-info">' . __('You can configure and manage installed plugins from this list.') . '</p>'; 162 163 $list 164 ->setList('plugin-activate') 165 ->setTab('plugins') 166 ->setModules($modules) 167 ->displayModules( 168 /* cols */array('expander', 'icon', 'name', 'version', 'desc', 'distrib', 'deps'), 169 /* actions */array('deactivate', 'delete', 'behavior') 170 ); 172 171 } 173 172 174 173 # Deactivated modules 175 174 if ($core->auth->isSuperAdmin()) { 176 $modules = $list->modules->getDisabledModules();177 if (!empty($modules)) {178 echo179 '<h3>'.__('Deactivated plugins').'</h3>'.180 '<p class="more-info">'.__('Deactivated plugins are installed but not usable. You can activate them from here.').'</p>';181 182 $list183 ->setList('plugin-deactivate')184 ->setTab('plugins')185 ->setModules($modules)186 ->displayModules(187 /* cols */array('expander', 'icon', 'name', 'version', 'desc', 'distrib'),188 /* actions */array('activate', 'delete')189 );190 }175 $modules = $list->modules->getDisabledModules(); 176 if (!empty($modules)) { 177 echo 178 '<h3>' . __('Deactivated plugins') . '</h3>' . 179 '<p class="more-info">' . __('Deactivated plugins are installed but not usable. You can activate them from here.') . '</p>'; 180 181 $list 182 ->setList('plugin-deactivate') 183 ->setTab('plugins') 184 ->setModules($modules) 185 ->displayModules( 186 /* cols */array('expander', 'icon', 'name', 'version', 'desc', 'distrib'), 187 /* actions */array('activate', 'delete') 188 ); 189 } 191 190 } 192 191 193 192 echo 194 '</div>';193 '</div>'; 195 194 196 195 if ($core->auth->isSuperAdmin() && $list->isWritablePath()) { 197 196 198 # New modules from repo199 $search= $list->getSearch();200 $modules = $search ? $list->store->search($search) : $list->store->get();201 202 if (!empty($search) || !empty($modules)) {203 echo204 '<div class="multi-part" id="new" title="'.__('Add plugins').'">'.205 '<h3>'.__('Add plugins from repository').'</h3>';206 207 $list208 ->setList('plugin-new')209 ->setTab('new')210 ->setModules($modules)211 ->displaySearch()212 ->displayIndex()213 ->displayModules(214 /* cols */ array('expander', 'name', 'score', 'version', 'desc','deps'),215 /* actions */array('install'),216 /* nav limit */true217 );218 219 echo220 '<p class="info vertical-separator">'.sprintf(221 __("Visit %s repository, the resources center for Dotclear."),222 '<a href="http://plugins.dotaddict.org/dc2/">Dotaddict</a>'223 ).224 '</p>'.225 226 '</div>';227 }228 229 # Add a new plugin230 echo231 '<div class="multi-part" id="addplugin" title="'.__('Install or upgrade manually').'">'.232 '<h3>'.__('Add plugins from a package').'</h3>'.233 '<p class="more-info">'.__('You can install plugins by uploading or downloading zip files.').'</p>';234 235 $list->displayManualForm();236 237 echo238 '</div>';197 # New modules from repo 198 $search = $list->getSearch(); 199 $modules = $search ? $list->store->search($search) : $list->store->get(); 200 201 if (!empty($search) || !empty($modules)) { 202 echo 203 '<div class="multi-part" id="new" title="' . __('Add plugins') . '">' . 204 '<h3>' . __('Add plugins from repository') . '</h3>'; 205 206 $list 207 ->setList('plugin-new') 208 ->setTab('new') 209 ->setModules($modules) 210 ->displaySearch() 211 ->displayIndex() 212 ->displayModules( 213 /* cols */array('expander', 'name', 'score', 'version', 'desc', 'deps'), 214 /* actions */array('install'), 215 /* nav limit */true 216 ); 217 218 echo 219 '<p class="info vertical-separator">' . sprintf( 220 __("Visit %s repository, the resources center for Dotclear."), 221 '<a href="http://plugins.dotaddict.org/dc2/">Dotaddict</a>' 222 ) . 223 '</p>' . 224 225 '</div>'; 226 } 227 228 # Add a new plugin 229 echo 230 '<div class="multi-part" id="addplugin" title="' . __('Install or upgrade manually') . '">' . 231 '<h3>' . __('Add plugins from a package') . '</h3>' . 232 '<p class="more-info">' . __('You can install plugins by uploading or downloading zip files.') . '</p>'; 233 234 $list->displayManualForm(); 235 236 echo 237 '</div>'; 239 238 } 240 239 … … 244 243 # -- Notice for super admin -- 245 244 if ($core->auth->isSuperAdmin() && !$list->isWritablePath()) { 246 echo247 '<p class="warning">'.__('Some functions are disabled, please give write access to your plugins directory to enable them.').'</p>';245 echo 246 '<p class="warning">' . __('Some functions are disabled, please give write access to your plugins directory to enable them.') . '</p>'; 248 247 } 249 248 -
admin/popup_link.php
r3725 r3730 32 32 '<p><label class="required" for="href"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Link URL:') . '</label> ' . 33 33 form::field('href', 35, 512, array( 34 'default' => html::escapeHTML($href),34 'default' => html::escapeHTML($href), 35 35 'extra_html' => 'required placeholder="' . __('URL') . '"' 36 36 )) . -
admin/post.php
r3725 r3730 561 561 562 562 form::datetime('post_dt', array( 563 'default' => html::escapeHTML(dt::str('%Y-%m-%dT%H:%M', strtotime($post_dt))),564 'class' => ($bad_dt ? 'invalid' : '')563 'default' => html::escapeHTML(dt::str('%Y-%m-%dT%H:%M', strtotime($post_dt))), 564 'class' => ($bad_dt ? 'invalid' : '') 565 565 )) . 566 */566 */ 567 567 '</p>', 568 568 'post_lang' => -
admin/post_media.php
r3167 r3730 11 11 # -- END LICENSE BLOCK ----------------------------------------- 12 12 13 require dirname(__FILE__) .'/../inc/admin/prepend.php';13 require dirname(__FILE__) . '/../inc/admin/prepend.php'; 14 14 15 15 dcPage::check('usage,contentadmin'); 16 16 17 $post_id = !empty($_REQUEST['post_id']) ? (integer) $_REQUEST['post_id'] : null;18 $media_id = !empty($_REQUEST['media_id']) ? (integer) $_REQUEST['media_id'] : null;17 $post_id = !empty($_REQUEST['post_id']) ? (integer) $_REQUEST['post_id'] : null; 18 $media_id = !empty($_REQUEST['media_id']) ? (integer) $_REQUEST['media_id'] : null; 19 19 $link_type = !empty($_REQUEST['link_type']) ? $_REQUEST['link_type'] : null; 20 20 21 21 if (!$post_id) { 22 exit;22 exit; 23 23 } 24 $rs = $core->blog->getPosts(array('post_id' => $post_id, 'post_type'=>''));24 $rs = $core->blog->getPosts(array('post_id' => $post_id, 'post_type' => '')); 25 25 if ($rs->isEmpty()) { 26 exit;26 exit; 27 27 } 28 28 29 29 try { 30 if ($post_id && $media_id && !empty($_REQUEST['attach'])) 31 { 32 $core->media = new dcMedia($core); 33 $core->media->addPostMedia($post_id,$media_id,$link_type); 30 if ($post_id && $media_id && !empty($_REQUEST['attach'])) { 31 $core->media = new dcMedia($core); 32 $core->media->addPostMedia($post_id, $media_id, $link_type); 34 33 if (!empty($_SERVER['HTTP_X_REQUESTED_WITH'])) { 35 34 header('Content-type: application/json'); 36 echo json_encode(array('url' => $core->getPostAdminURL($rs->post_type, $post_id,false)));35 echo json_encode(array('url' => $core->getPostAdminURL($rs->post_type, $post_id, false))); 37 36 exit(); 38 37 } else { 39 http::redirect($core->getPostAdminURL($rs->post_type, $post_id,false));38 http::redirect($core->getPostAdminURL($rs->post_type, $post_id, false)); 40 39 } 41 }40 } 42 41 43 $core->media = new dcMedia($core);44 $f = $core->media->getPostMedia($post_id,$media_id,$link_type);45 if (empty($f)) {46 $post_id = $media_id = null;47 throw new Exception(__('This attachment does not exist'));48 }49 $f = $f[0];42 $core->media = new dcMedia($core); 43 $f = $core->media->getPostMedia($post_id, $media_id, $link_type); 44 if (empty($f)) { 45 $post_id = $media_id = null; 46 throw new Exception(__('This attachment does not exist')); 47 } 48 $f = $f[0]; 50 49 } catch (Exception $e) { 51 $core->error->add($e->getMessage());50 $core->error->add($e->getMessage()); 52 51 } 53 52 54 53 # Remove a media from en 55 if (($post_id && $media_id) || $core->error->flag()) 56 { 57 if (!empty($_POST['remove'])) 58 { 59 $core->media->removePostMedia($post_id,$media_id,$link_type); 54 if (($post_id && $media_id) || $core->error->flag()) { 55 if (!empty($_POST['remove'])) { 56 $core->media->removePostMedia($post_id, $media_id, $link_type); 60 57 61 dcPage::addSuccessNotice(__('Attachment has been successfully removed.')); 62 http::redirect($core->getPostAdminURL($rs->post_type,$post_id,false)); 63 } 64 elseif (isset($_POST['post_id'])) { 65 http::redirect($core->getPostAdminURL($rs->post_type,$post_id,false)); 66 } 58 dcPage::addSuccessNotice(__('Attachment has been successfully removed.')); 59 http::redirect($core->getPostAdminURL($rs->post_type, $post_id, false)); 60 } elseif (isset($_POST['post_id'])) { 61 http::redirect($core->getPostAdminURL($rs->post_type, $post_id, false)); 62 } 67 63 68 if (!empty($_GET['remove'])) 69 { 70 dcPage::open(__('Remove attachment')); 64 if (!empty($_GET['remove'])) { 65 dcPage::open(__('Remove attachment')); 71 66 72 echo '<h2>'.__('Attachment').' › <span class="page-title">'.__('confirm removal').'</span></h2>';67 echo '<h2>' . __('Attachment') . ' › <span class="page-title">' . __('confirm removal') . '</span></h2>'; 73 68 74 echo75 '<form action="'.$core->adminurl->get("admin.post.media").'" method="post">'.76 '<p>'.__('Are you sure you want to remove this attachment?').'</p>'.77 '<p><input type="submit" class="reset" value="'.__('Cancel').'" /> '.78 ' <input type="submit" class="delete" name="remove" value="'.__('Yes').'" />'.79 form::hidden('post_id',$post_id).80 form::hidden('media_id',$media_id).81 $core->formNonce().'</p>'.82 '</form>';69 echo 70 '<form action="' . $core->adminurl->get("admin.post.media") . '" method="post">' . 71 '<p>' . __('Are you sure you want to remove this attachment?') . '</p>' . 72 '<p><input type="submit" class="reset" value="' . __('Cancel') . '" /> ' . 73 ' <input type="submit" class="delete" name="remove" value="' . __('Yes') . '" />' . 74 form::hidden('post_id', $post_id) . 75 form::hidden('media_id', $media_id) . 76 $core->formNonce() . '</p>' . 77 '</form>'; 83 78 84 dcPage::close();85 exit;86 }79 dcPage::close(); 80 exit; 81 } 87 82 } -
admin/posts_actions.php
r2720 r3730 11 11 # -- END LICENSE BLOCK ----------------------------------------- 12 12 13 /* ### THIS FILE IS DEPRECATED ### */13 /* ### THIS FILE IS DEPRECATED ### */ 14 14 /* ### IT IS ONLY USED FOR PLUGINS COMPATIBILITY ### */ 15 15 16 require dirname(__FILE__) .'/../inc/admin/prepend.php';16 require dirname(__FILE__) . '/../inc/admin/prepend.php'; 17 17 18 18 dcPage::check('usage,contentadmin'); 19 19 20 20 if (isset($_REQUEST['redir'])) { 21 $u = explode('?',$_REQUEST['redir']);22 $uri = $u[0];23 if (isset($u[1])) {24 parse_str($u[1],$args);25 }26 $args['redir'] = $_REQUEST['redir'];21 $u = explode('?', $_REQUEST['redir']); 22 $uri = $u[0]; 23 if (isset($u[1])) { 24 parse_str($u[1], $args); 25 } 26 $args['redir'] = $_REQUEST['redir']; 27 27 } else { 28 $uri= $core->adminurl->get("admin.posts");29 $args=array();28 $uri = $core->adminurl->get("admin.posts"); 29 $args = array(); 30 30 } 31 31 32 $posts_actions_page = new dcPostsActionsPage($core, $uri,$args);32 $posts_actions_page = new dcPostsActionsPage($core, $uri, $args); 33 33 $posts_actions_page->setEnableRedirSelection(false); 34 34 $posts_actions_page->process(); -
admin/services.php
r3614 r3730 12 12 13 13 #if (isset($_GET['dcxd'])) { 14 # $_COOKIE['dcxd'] = $_GET['dcxd'];14 # $_COOKIE['dcxd'] = $_GET['dcxd']; 15 15 #} 16 16 17 require dirname(__FILE__) .'/../inc/admin/prepend.php';18 19 $core->rest->addFunction('checkNewsUpdate', array('dcRestMethods','checkNewsUpdate'));20 $core->rest->addFunction('checkCoreUpdate', array('dcRestMethods','checkCoreUpdate'));21 $core->rest->addFunction('getPostById', array('dcRestMethods','getPostById'));22 $core->rest->addFunction('getCommentById', array('dcRestMethods','getCommentById'));23 $core->rest->addFunction('quickPost', array('dcRestMethods','quickPost'));24 $core->rest->addFunction('validatePostMarkup', array('dcRestMethods','validatePostMarkup'));25 $core->rest->addFunction('getZipMediaContent', array('dcRestMethods','getZipMediaContent'));26 $core->rest->addFunction('getMeta', array('dcRestMethods','getMeta'));27 $core->rest->addFunction('delMeta', array('dcRestMethods','delMeta'));28 $core->rest->addFunction('setPostMeta', array('dcRestMethods','setPostMeta'));29 $core->rest->addFunction('searchMeta', array('dcRestMethods','searchMeta'));30 $core->rest->addFunction('setSectionFold', array('dcRestMethods','setSectionFold'));31 $core->rest->addFunction('getModuleById', array('dcRestMethods','getModuleById'));17 require dirname(__FILE__) . '/../inc/admin/prepend.php'; 18 19 $core->rest->addFunction('checkNewsUpdate', array('dcRestMethods', 'checkNewsUpdate')); 20 $core->rest->addFunction('checkCoreUpdate', array('dcRestMethods', 'checkCoreUpdate')); 21 $core->rest->addFunction('getPostById', array('dcRestMethods', 'getPostById')); 22 $core->rest->addFunction('getCommentById', array('dcRestMethods', 'getCommentById')); 23 $core->rest->addFunction('quickPost', array('dcRestMethods', 'quickPost')); 24 $core->rest->addFunction('validatePostMarkup', array('dcRestMethods', 'validatePostMarkup')); 25 $core->rest->addFunction('getZipMediaContent', array('dcRestMethods', 'getZipMediaContent')); 26 $core->rest->addFunction('getMeta', array('dcRestMethods', 'getMeta')); 27 $core->rest->addFunction('delMeta', array('dcRestMethods', 'delMeta')); 28 $core->rest->addFunction('setPostMeta', array('dcRestMethods', 'setPostMeta')); 29 $core->rest->addFunction('searchMeta', array('dcRestMethods', 'searchMeta')); 30 $core->rest->addFunction('setSectionFold', array('dcRestMethods', 'setSectionFold')); 31 $core->rest->addFunction('getModuleById', array('dcRestMethods', 'getModuleById')); 32 32 33 33 $core->rest->serve(); … … 36 36 class dcRestMethods 37 37 { 38 public static function checkNewsUpdate($core,$get) 39 { 40 # Dotclear news 41 42 $rsp = new xmlTag('news'); 43 $rsp->check = false; 44 $ret = __('Dotclear news not available'); 45 46 if ($core->auth->user_prefs->dashboard->dcnews) { 47 try 48 { 49 50 if (empty($GLOBALS['__resources']['rss_news'])) { 51 throw new Exception(); 52 } 53 $feed_reader = new feedReader; 54 $feed_reader->setCacheDir(DC_TPL_CACHE); 55 $feed_reader->setTimeout(2); 56 $feed_reader->setUserAgent('Dotclear - http://www.dotclear.org/'); 57 $feed = $feed_reader->parse($GLOBALS['__resources']['rss_news']); 58 if ($feed) 59 { 60 $ret = '<div class="box medium dc-box"><h3>'.__('Dotclear news').'</h3><dl id="news">'; 61 $i = 1; 62 foreach ($feed->items as $item) 63 { 64 $dt = isset($item->link) ? '<a href="'.$item->link.'" class="outgoing" title="'.$item->title.'">'. 65 $item->title.' <img src="images/outgoing-blue.png" alt="" /></a>' : $item->title; 66 67 if ($i < 3) { 68 $ret .= 69 '<dt>'.$dt.'</dt>'. 70 '<dd><p><strong>'.dt::dt2str(__('%d %B %Y:'),$item->pubdate,'Europe/Paris').'</strong> '. 71 '<em>'.text::cutString(html::clean($item->content),120).'...</em></p></dd>'; 72 } else { 73 $ret .= 74 '<dt>'.$dt.'</dt>'. 75 '<dd>'.dt::dt2str(__('%d %B %Y:'),$item->pubdate,'Europe/Paris').'</dd>'; 76 } 77 $i++; 78 if ($i > 2) { break; } 79 } 80 $ret .= '</dl></div>'; 81 $rsp->check = true; 82 } 83 } 84 catch (Exception $e) {} 85 } 86 $rsp->ret = $ret; 87 return $rsp; 88 } 89 90 public static function checkCoreUpdate($core,$get) 91 { 92 # Dotclear updates notifications 93 94 $rsp = new xmlTag('update'); 95 $rsp->check = false; 96 $ret = __('Dotclear update not available'); 97 98 if ($core->auth->isSuperAdmin() && !DC_NOT_UPDATE && is_readable(DC_DIGESTS) && 99 !$core->auth->user_prefs->dashboard->nodcupdate) 100 { 101 $updater = new dcUpdate(DC_UPDATE_URL,'dotclear',DC_UPDATE_VERSION,DC_TPL_CACHE.'/versions'); 102 $new_v = $updater->check(DC_VERSION); 103 $version_info = $new_v ? $updater->getInfoURL() : ''; 104 105 if ($updater->getNotify() && $new_v) { 106 // Check PHP version required 107 if (version_compare(phpversion(),$updater->getPHPVersion()) >= 0) { 108 $ret = 109 '<div class="dc-update"><h3>'.sprintf(__('Dotclear %s is available!'),$new_v).'</h3> '. 110 '<p><a class="button submit" href="'.$core->adminurl->get("admin.update").'">'.sprintf(__('Upgrade now'),$new_v).'</a> '. 111 '<a class="button" href="'.$core->adminurl->get("admin.update", array('hide_msg' => 1)).'">'.__('Remind me later').'</a>'. 112 ($version_info ? ' </p>'. 113 '<p class="updt-info"><a href="'.$version_info.'">'.__('Information about this version').'</a>' : '').'</p>'. 114 '</div>'; 115 } else { 116 $ret = '<p class="info">'. 117 sprintf(__('A new version of Dotclear is available but needs PHP version ≥ %s, your\'s is currently %s'), 118 $updater->getPHPVersion(),phpversion()). 119 '</p>'; 120 } 121 $rsp->check = true; 122 } else { 123 if (version_compare(phpversion(),DC_NEXT_REQUIRED_PHP,'<')) { 124 $ret = '<p class="info">'. 125 sprintf(__('The next versions of Dotclear will not support PHP version < %s, your\'s is currently %s'), 126 DC_NEXT_REQUIRED_PHP,phpversion()). 127 '</p>'; 128 $rsp->check = true; 129 } 130 } 131 } 132 $rsp->ret = $ret; 133 return $rsp; 134 } 135 136 public static function getPostById($core,$get) 137 { 138 if (empty($get['id'])) { 139 throw new Exception('No post ID'); 140 } 141 142 $params = array('post_id' => (integer) $get['id']); 143 144 if (isset($get['post_type'])) { 145 $params['post_type'] = $get['post_type']; 146 } 147 148 $rs = $core->blog->getPosts($params); 149 150 if ($rs->isEmpty()) { 151 throw new Exception('No post for this ID'); 152 } 153 154 $rsp = new xmlTag('post'); 155 $rsp->id = $rs->post_id; 156 157 $rsp->blog_id($rs->blog_id); 158 $rsp->user_id($rs->user_id); 159 $rsp->cat_id($rs->cat_id); 160 $rsp->post_dt($rs->post_dt); 161 $rsp->post_creadt($rs->post_creadt); 162 $rsp->post_upddt($rs->post_upddt); 163 $rsp->post_format($rs->post_format); 164 $rsp->post_url($rs->post_url); 165 $rsp->post_lang($rs->post_lang); 166 $rsp->post_title($rs->post_title); 167 $rsp->post_excerpt($rs->post_excerpt); 168 $rsp->post_excerpt_xhtml($rs->post_excerpt_xhtml); 169 $rsp->post_content($rs->post_content); 170 $rsp->post_content_xhtml($rs->post_content_xhtml); 171 $rsp->post_notes($rs->post_notes); 172 $rsp->post_status($rs->post_status); 173 $rsp->post_selected($rs->post_selected); 174 $rsp->post_open_comment($rs->post_open_comment); 175 $rsp->post_open_tb($rs->post_open_tb); 176 $rsp->nb_comment($rs->nb_comment); 177 $rsp->nb_trackback($rs->nb_trackback); 178 $rsp->user_name($rs->user_name); 179 $rsp->user_firstname($rs->user_firstname); 180 $rsp->user_displayname($rs->user_displayname); 181 $rsp->user_email($rs->user_email); 182 $rsp->user_url($rs->user_url); 183 $rsp->cat_title($rs->cat_title); 184 $rsp->cat_url($rs->cat_url); 185 186 $rsp->post_display_content($rs->getContent(true)); 187 $rsp->post_display_excerpt($rs->getExcerpt(true)); 188 189 $metaTag = new xmlTag('meta'); 190 if (($meta = @unserialize($rs->post_meta)) !== false) 191 { 192 foreach ($meta as $K => $V) 193 { 194 foreach ($V as $v) { 195 $metaTag->$K($v); 196 } 197 } 198 } 199 $rsp->post_meta($metaTag); 200 201 return $rsp; 202 } 203 204 public static function getCommentById($core,$get) 205 { 206 if (empty($get['id'])) { 207 throw new Exception('No comment ID'); 208 } 209 210 $rs = $core->blog->getComments(array('comment_id' => (integer) $get['id'])); 211 212 if ($rs->isEmpty()) { 213 throw new Exception('No comment for this ID'); 214 } 215 216 $rsp = new xmlTag('post'); 217 $rsp->id = $rs->comment_id; 218 219 $rsp->comment_dt($rs->comment_dt); 220 $rsp->comment_upddt($rs->comment_upddt); 221 $rsp->comment_author($rs->comment_author); 222 $rsp->comment_site($rs->comment_site); 223 $rsp->comment_content($rs->comment_content); 224 $rsp->comment_trackback($rs->comment_trackback); 225 $rsp->comment_status($rs->comment_status); 226 $rsp->post_title($rs->post_title); 227 $rsp->post_url($rs->post_url); 228 $rsp->post_id($rs->post_id); 229 $rsp->post_dt($rs->post_dt); 230 $rsp->user_id($rs->user_id); 231 232 $rsp->comment_display_content($rs->getContent(true)); 233 234 if ($core->auth->userID()) { 235 $rsp->comment_ip($rs->comment_ip); 236 $rsp->comment_email($rs->comment_email); 237 $rsp->comment_spam_disp(dcAntispam::statusMessage($rs)); 238 } 239 240 return $rsp; 241 } 242 243 public static function quickPost($core,$get,$post) 244 { 245 # Create category 246 if (!empty($post['new_cat_title']) && $core->auth->check('categories', $core->blog->id)) { 247 248 $cur_cat = $core->con->openCursor($core->prefix.'category'); 249 $cur_cat->cat_title = $post['new_cat_title']; 250 $cur_cat->cat_url = ''; 251 252 $parent_cat = !empty($post['new_cat_parent']) ? $post['new_cat_parent'] : ''; 253 254 # --BEHAVIOR-- adminBeforeCategoryCreate 255 $core->callBehavior('adminBeforeCategoryCreate', $cur_cat); 256 257 $post['cat_id'] = $core->blog->addCategory($cur_cat, (integer) $parent_cat); 258 259 # --BEHAVIOR-- adminAfterCategoryCreate 260 $core->callBehavior('adminAfterCategoryCreate', $cur_cat, $post['cat_id']); 261 } 262 263 $cur = $core->con->openCursor($core->prefix.'post'); 264 265 $cur->post_title = !empty($post['post_title']) ? $post['post_title'] : ''; 266 $cur->user_id = $core->auth->userID(); 267 $cur->post_content = !empty($post['post_content']) ? $post['post_content'] : ''; 268 $cur->cat_id = !empty($post['cat_id']) ? (integer) $post['cat_id'] : null; 269 $cur->post_format = !empty($post['post_format']) ? $post['post_format'] : 'xhtml'; 270 $cur->post_lang = !empty($post['post_lang']) ? $post['post_lang'] : ''; 271 $cur->post_status = !empty($post['post_status']) ? (integer) $post['post_status'] : 0; 272 $cur->post_open_comment = (integer) $core->blog->settings->system->allow_comments; 273 $cur->post_open_tb = (integer) $core->blog->settings->system->allow_trackbacks; 274 275 # --BEHAVIOR-- adminBeforePostCreate 276 $core->callBehavior('adminBeforePostCreate',$cur); 277 278 $return_id = $core->blog->addPost($cur); 279 280 # --BEHAVIOR-- adminAfterPostCreate 281 $core->callBehavior('adminAfterPostCreate',$cur,$return_id); 282 283 $rsp = new xmlTag('post'); 284 $rsp->id = $return_id; 285 286 $post = $core->blog->getPosts(array('post_id' => $return_id)); 287 288 $rsp->post_status = $post->post_status; 289 $rsp->post_url = $post->getURL(); 290 return $rsp; 291 } 292 293 public static function validatePostMarkup($core,$get,$post) 294 { 295 if (!isset($post['excerpt'])) { 296 throw new Exception('No entry excerpt'); 297 } 298 299 if (!isset($post['content'])) { 300 throw new Exception('No entry content'); 301 } 302 303 if (empty($post['format'])) { 304 throw new Exception('No entry format'); 305 } 306 307 if (!isset($post['lang'])) { 308 throw new Exception('No entry lang'); 309 } 310 311 $excerpt = $post['excerpt']; 312 $excerpt_xhtml = ''; 313 $content = $post['content']; 314 $content_xhtml = ''; 315 $format = $post['format']; 316 $lang = $post['lang']; 317 318 $core->blog->setPostContent(0,$format,$lang,$excerpt,$excerpt_xhtml,$content,$content_xhtml); 319 320 $rsp = new xmlTag('result'); 321 322 $v = htmlValidator::validate($excerpt_xhtml.$content_xhtml); 323 324 $rsp->valid($v['valid']); 325 $rsp->errors($v['errors']); 326 327 return $rsp; 328 } 329 330 public static function getZipMediaContent($core,$get,$post) 331 { 332 if (empty($get['id'])) { 333 throw new Exception('No media ID'); 334 } 335 336 $id = (integer) $get['id']; 337 338 if (!$core->auth->check('media,media_admin',$core->blog)) { 339 throw new Exception('Permission denied'); 340 } 341 342 try { 343 $core->media = new dcMedia($core); 344 $file = $core->media->getFile($id); 345 } catch (Exception $e) {} 346 347 if ($file === null || $file->type != 'application/zip' || !$file->editable) { 348 throw new Exception('Not a valid file'); 349 } 350 351 $rsp = new xmlTag('result'); 352 $content = $core->media->getZipContent($file); 353 354 foreach ($content as $k => $v) { 355 $rsp->file($k); 356 } 357 358 return $rsp; 359 } 360 361 public static function getMeta($core,$get) 362 { 363 $postid = !empty($get['postId']) ? $get['postId'] : null; 364 $limit = !empty($get['limit']) ? $get['limit'] : null; 365 $metaId = !empty($get['metaId']) ? $get['metaId'] : null; 366 $metaType = !empty($get['metaType']) ? $get['metaType'] : null; 367 368 $sortby = !empty($get['sortby']) ? $get['sortby'] : 'meta_type,asc'; 369 370 $rs = $core->meta->getMetadata(array( 371 'meta_type' => $metaType, 372 'limit' => $limit, 373 'meta_id' => $metaId, 374 'post_id' => $postid)); 375 $rs = $core->meta->computeMetaStats($rs); 376 377 $sortby = explode(',',$sortby); 378 $sort = $sortby[0]; 379 $order = isset($sortby[1]) ? $sortby[1] : 'asc'; 380 381 switch ($sort) { 382 case 'metaId': 383 $sort = 'meta_id_lower'; 384 break; 385 case 'count': 386 $sort = 'count'; 387 break; 388 case 'metaType': 389 $sort = 'meta_type'; 390 break; 391 default: 392 $sort = 'meta_type'; 393 } 394 395 $rs->sort($sort,$order); 396 397 $rsp = new xmlTag(); 398 399 while ($rs->fetch()) 400 { 401 $metaTag = new xmlTag('meta'); 402 $metaTag->type = $rs->meta_type; 403 $metaTag->uri = rawurlencode($rs->meta_id); 404 $metaTag->count = $rs->count; 405 $metaTag->percent = $rs->percent; 406 $metaTag->roundpercent = $rs->roundpercent; 407 $metaTag->CDATA($rs->meta_id); 408 409 $rsp->insertNode($metaTag); 410 } 411 412 return $rsp; 413 } 414 415 public static function setPostMeta($core,$get,$post) 416 { 417 if (empty($post['postId'])) { 418 throw new Exception('No post ID'); 419 } 420 421 if (empty($post['meta']) && $post['meta'] != '0') { 422 throw new Exception('No meta'); 423 } 424 425 if (empty($post['metaType'])) { 426 throw new Exception('No meta type'); 427 } 428 429 # Get previous meta for post 430 $post_meta = $core->meta->getMetadata(array( 431 'meta_type' => $post['metaType'], 432 'post_id' => $post['postId'])); 433 $pm = array(); 434 while ($post_meta->fetch()) { 435 $pm[] = $post_meta->meta_id; 436 } 437 438 foreach ($core->meta->splitMetaValues($post['meta']) as $m) 439 { 440 if (!in_array($m,$pm)) { 441 $core->meta->setPostMeta($post['postId'],$post['metaType'],$m); 442 } 443 } 444 445 return true; 446 } 447 448 public static function delMeta($core,$get,$post) 449 { 450 if (empty($post['postId'])) { 451 throw new Exception('No post ID'); 452 } 453 454 if (empty($post['metaId']) && $post['metaId'] != '0') { 455 throw new Exception('No meta ID'); 456 } 457 458 if (empty($post['metaType'])) { 459 throw new Exception('No meta type'); 460 } 461 462 $core->meta->delPostMeta($post['postId'],$post['metaType'],$post['metaId']); 463 464 return true; 465 } 466 467 public static function searchMeta($core,$get) 468 { 469 $q = !empty($get['q']) ? $get['q'] : null; 470 $metaType = !empty($get['metaType']) ? $get['metaType'] : null; 471 472 $sortby = !empty($get['sortby']) ? $get['sortby'] : 'meta_type,asc'; 473 474 $rs = $core->meta->getMetadata(array('meta_type' => $metaType)); 475 $rs = $core->meta->computeMetaStats($rs); 476 477 $sortby = explode(',',$sortby); 478 $sort = $sortby[0]; 479 $order = isset($sortby[1]) ? $sortby[1] : 'asc'; 480 481 switch ($sort) { 482 case 'metaId': 483 $sort = 'meta_id_lower'; 484 break; 485 case 'count': 486 $sort = 'count'; 487 break; 488 case 'metaType': 489 $sort = 'meta_type'; 490 break; 491 default: 492 $sort = 'meta_type'; 493 } 494 495 $rs->sort($sort,$order); 496 497 $rsp = new xmlTag(); 498 499 while ($rs->fetch()) 500 { 501 if (stripos($rs->meta_id,$q) === 0) { 502 $metaTag = new xmlTag('meta'); 503 $metaTag->type = $rs->meta_type; 504 $metaTag->uri = rawurlencode($rs->meta_id); 505 $metaTag->count = $rs->count; 506 $metaTag->percent = $rs->percent; 507 $metaTag->roundpercent = $rs->roundpercent; 508 $metaTag->CDATA($rs->meta_id); 509 510 $rsp->insertNode($metaTag); 511 } 512 } 513 514 return $rsp; 515 } 516 517 public static function setSectionFold($core,$get,$post) 518 { 519 if (empty($post['section'])) { 520 throw new Exception('No section name'); 521 } 522 if ($core->auth->user_prefs->toggles === null) { 523 $core->auth->user_prefs->addWorkspace('toggles'); 524 } 525 $section = $post['section']; 526 $status = isset($post['value']) && ($post['value'] != 0); 527 if ($core->auth->user_prefs->toggles->prefExists('unfolded_sections')) { 528 $toggles = explode(',',trim($core->auth->user_prefs->toggles->unfolded_sections)); 529 } else { 530 $toggles = array(); 531 } 532 $k = array_search($section,$toggles); 533 if ($status) { // true == Fold section ==> remove it from unfolded list 534 if ($k !== false) { 535 unset($toggles[$k]); 536 } 537 } else { // false == unfold section ==> add it to unfolded list 538 if ($k === false) { 539 $toggles[]=$section; 540 }; 541 } 542 $core->auth->user_prefs->toggles->put('unfolded_sections',join(',',$toggles)); 543 return true; 544 } 545 546 public static function getModuleById($core, $get, $post) 547 { 548 if (empty($get['id'])) { 549 throw new Exception('No module ID'); 550 } 551 if (empty($get['list'])) { 552 throw new Exception('No list ID'); 553 } 554 555 $id = $get['id']; 556 $list = $get['list']; 557 $module = array(); 558 559 if ($list == 'plugin-activate') { 560 $modules = $core->plugins->getModules(); 561 if (empty($modules) || !isset($modules[$id])) { 562 throw new Exception('Unknow module ID'); 563 } 564 $module = $modules[$id]; 565 } 566 elseif ($list == 'plugin-new') { 567 $store = new dcStore( 568 $core->plugins, 569 $core->blog->settings->system->store_plugin_url 570 ); 571 $store->check(); 572 573 $modules = $store->get(); 574 if (empty($modules) || !isset($modules[$id])) { 575 throw new Exception('Unknow module ID'); 576 } 577 $module = $modules[$id]; 578 } 579 else { 580 // behavior not implemented yet 581 } 582 583 if (empty($module)) { 584 throw new Exception('Unknow module ID'); 585 } 586 587 $module = adminModulesList::sanitizeModule($id, $module); 588 589 $rsp = new xmlTag('module'); 590 $rsp->id = $id; 591 592 foreach($module as $k => $v) { 593 $rsp->{$k}((string) $v); 594 } 595 596 return $rsp; 597 } 38 public static function checkNewsUpdate($core, $get) 39 { 40 # Dotclear news 41 42 $rsp = new xmlTag('news'); 43 $rsp->check = false; 44 $ret = __('Dotclear news not available'); 45 46 if ($core->auth->user_prefs->dashboard->dcnews) { 47 try 48 { 49 50 if (empty($GLOBALS['__resources']['rss_news'])) { 51 throw new Exception(); 52 } 53 $feed_reader = new feedReader; 54 $feed_reader->setCacheDir(DC_TPL_CACHE); 55 $feed_reader->setTimeout(2); 56 $feed_reader->setUserAgent('Dotclear - http://www.dotclear.org/'); 57 $feed = $feed_reader->parse($GLOBALS['__resources']['rss_news']); 58 if ($feed) { 59 $ret = '<div class="box medium dc-box"><h3>' . __('Dotclear news') . '</h3><dl id="news">'; 60 $i = 1; 61 foreach ($feed->items as $item) { 62 $dt = isset($item->link) ? '<a href="' . $item->link . '" class="outgoing" title="' . $item->title . '">' . 63 $item->title . ' <img src="images/outgoing-blue.png" alt="" /></a>' : $item->title; 64 65 if ($i < 3) { 66 $ret .= 67 '<dt>' . $dt . '</dt>' . 68 '<dd><p><strong>' . dt::dt2str(__('%d %B %Y:'), $item->pubdate, 'Europe/Paris') . '</strong> ' . 69 '<em>' . text::cutString(html::clean($item->content), 120) . '...</em></p></dd>'; 70 } else { 71 $ret .= 72 '<dt>' . $dt . '</dt>' . 73 '<dd>' . dt::dt2str(__('%d %B %Y:'), $item->pubdate, 'Europe/Paris') . '</dd>'; 74 } 75 $i++; 76 if ($i > 2) {break;} 77 } 78 $ret .= '</dl></div>'; 79 $rsp->check = true; 80 } 81 } catch (Exception $e) {} 82 } 83 $rsp->ret = $ret; 84 return $rsp; 85 } 86 87 public static function checkCoreUpdate($core, $get) 88 { 89 # Dotclear updates notifications 90 91 $rsp = new xmlTag('update'); 92 $rsp->check = false; 93 $ret = __('Dotclear update not available'); 94 95 if ($core->auth->isSuperAdmin() && !DC_NOT_UPDATE && is_readable(DC_DIGESTS) && 96 !$core->auth->user_prefs->dashboard->nodcupdate) { 97 $updater = new dcUpdate(DC_UPDATE_URL, 'dotclear', DC_UPDATE_VERSION, DC_TPL_CACHE . '/versions'); 98 $new_v = $updater->check(DC_VERSION); 99 $version_info = $new_v ? $updater->getInfoURL() : ''; 100 101 if ($updater->getNotify() && $new_v) { 102 // Check PHP version required 103 if (version_compare(phpversion(), $updater->getPHPVersion()) >= 0) { 104 $ret = 105 '<div class="dc-update"><h3>' . sprintf(__('Dotclear %s is available!'), $new_v) . '</h3> ' . 106 '<p><a class="button submit" href="' . $core->adminurl->get("admin.update") . '">' . sprintf(__('Upgrade now'), $new_v) . '</a> ' . 107 '<a class="button" href="' . $core->adminurl->get("admin.update", array('hide_msg' => 1)) . '">' . __('Remind me later') . '</a>' . 108 ($version_info ? ' </p>' . 109 '<p class="updt-info"><a href="' . $version_info . '">' . __('Information about this version') . '</a>' : '') . '</p>' . 110 '</div>'; 111 } else { 112 $ret = '<p class="info">' . 113 sprintf(__('A new version of Dotclear is available but needs PHP version ≥ %s, your\'s is currently %s'), 114 $updater->getPHPVersion(), phpversion()) . 115 '</p>'; 116 } 117 $rsp->check = true; 118 } else { 119 if (version_compare(phpversion(), DC_NEXT_REQUIRED_PHP, '<')) { 120 $ret = '<p class="info">' . 121 sprintf(__('The next versions of Dotclear will not support PHP version < %s, your\'s is currently %s'), 122 DC_NEXT_REQUIRED_PHP, phpversion()) . 123 '</p>'; 124 $rsp->check = true; 125 } 126 } 127 } 128 $rsp->ret = $ret; 129 return $rsp; 130 } 131 132 public static function getPostById($core, $get) 133 { 134 if (empty($get['id'])) { 135 throw new Exception('No post ID'); 136 } 137 138 $params = array('post_id' => (integer) $get['id']); 139 140 if (isset($get['post_type'])) { 141 $params['post_type'] = $get['post_type']; 142 } 143 144 $rs = $core->blog->getPosts($params); 145 146 if ($rs->isEmpty()) { 147 throw new Exception('No post for this ID'); 148 } 149 150 $rsp = new xmlTag('post'); 151 $rsp->id = $rs->post_id; 152 153 $rsp->blog_id($rs->blog_id); 154 $rsp->user_id($rs->user_id); 155 $rsp->cat_id($rs->cat_id); 156 $rsp->post_dt($rs->post_dt); 157 $rsp->post_creadt($rs->post_creadt); 158 $rsp->post_upddt($rs->post_upddt); 159 $rsp->post_format($rs->post_format); 160 $rsp->post_url($rs->post_url); 161 $rsp->post_lang($rs->post_lang); 162 $rsp->post_title($rs->post_title); 163 $rsp->post_excerpt($rs->post_excerpt); 164 $rsp->post_excerpt_xhtml($rs->post_excerpt_xhtml); 165 $rsp->post_content($rs->post_content); 166 $rsp->post_content_xhtml($rs->post_content_xhtml); 167 $rsp->post_notes($rs->post_notes); 168 $rsp->post_status($rs->post_status); 169 $rsp->post_selected($rs->post_selected); 170 $rsp->post_open_comment($rs->post_open_comment); 171 $rsp->post_open_tb($rs->post_open_tb); 172 $rsp->nb_comment($rs->nb_comment); 173 $rsp->nb_trackback($rs->nb_trackback); 174 $rsp->user_name($rs->user_name); 175 $rsp->user_firstname($rs->user_firstname); 176 $rsp->user_displayname($rs->user_displayname); 177 $rsp->user_email($rs->user_email); 178 $rsp->user_url($rs->user_url); 179 $rsp->cat_title($rs->cat_title); 180 $rsp->cat_url($rs->cat_url); 181 182 $rsp->post_display_content($rs->getContent(true)); 183 $rsp->post_display_excerpt($rs->getExcerpt(true)); 184 185 $metaTag = new xmlTag('meta'); 186 if (($meta = @unserialize($rs->post_meta)) !== false) { 187 foreach ($meta as $K => $V) { 188 foreach ($V as $v) { 189 $metaTag->$K($v); 190 } 191 } 192 } 193 $rsp->post_meta($metaTag); 194 195 return $rsp; 196 } 197 198 public static function getCommentById($core, $get) 199 { 200 if (empty($get['id'])) { 201 throw new Exception('No comment ID'); 202 } 203 204 $rs = $core->blog->getComments(array('comment_id' => (integer) $get['id'])); 205 206 if ($rs->isEmpty()) { 207 throw new Exception('No comment for this ID'); 208 } 209 210 $rsp = new xmlTag('post'); 211 $rsp->id = $rs->comment_id; 212 213 $rsp->comment_dt($rs->comment_dt); 214 $rsp->comment_upddt($rs->comment_upddt); 215 $rsp->comment_author($rs->comment_author); 216 $rsp->comment_site($rs->comment_site); 217 $rsp->comment_content($rs->comment_content); 218 $rsp->comment_trackback($rs->comment_trackback); 219 $rsp->comment_status($rs->comment_status); 220 $rsp->post_title($rs->post_title); 221 $rsp->post_url($rs->post_url); 222 $rsp->post_id($rs->post_id); 223 $rsp->post_dt($rs->post_dt); 224 $rsp->user_id($rs->user_id); 225 226 $rsp->comment_display_content($rs->getContent(true)); 227 228 if ($core->auth->userID()) { 229 $rsp->comment_ip($rs->comment_ip); 230 $rsp->comment_email($rs->comment_email); 231 $rsp->comment_spam_disp(dcAntispam::statusMessage($rs)); 232 } 233 234 return $rsp; 235 } 236 237 public static function quickPost($core, $get, $post) 238 { 239 # Create category 240 if (!empty($post['new_cat_title']) && $core->auth->check('categories', $core->blog->id)) { 241 242 $cur_cat = $core->con->openCursor($core->prefix . 'category'); 243 $cur_cat->cat_title = $post['new_cat_title']; 244 $cur_cat->cat_url = ''; 245 246 $parent_cat = !empty($post['new_cat_parent']) ? $post['new_cat_parent'] : ''; 247 248 # --BEHAVIOR-- adminBeforeCategoryCreate 249 $core->callBehavior('adminBeforeCategoryCreate', $cur_cat); 250 251 $post['cat_id'] = $core->blog->addCategory($cur_cat, (integer) $parent_cat); 252 253 # --BEHAVIOR-- adminAfterCategoryCreate 254 $core->callBehavior('adminAfterCategoryCreate', $cur_cat, $post['cat_id']); 255 } 256 257 $cur = $core->con->openCursor($core->prefix . 'post'); 258 259 $cur->post_title = !empty($post['post_title']) ? $post['post_title'] : ''; 260 $cur->user_id = $core->auth->userID(); 261 $cur->post_content = !empty($post['post_content']) ? $post['post_content'] : ''; 262 $cur->cat_id = !empty($post['cat_id']) ? (integer) $post['cat_id'] : null; 263 $cur->post_format = !empty($post['post_format']) ? $post['post_format'] : 'xhtml'; 264 $cur->post_lang = !empty($post['post_lang']) ? $post['post_lang'] : ''; 265 $cur->post_status = !empty($post['post_status']) ? (integer) $post['post_status'] : 0; 266 $cur->post_open_comment = (integer) $core->blog->settings->system->allow_comments; 267 $cur->post_open_tb = (integer) $core->blog->settings->system->allow_trackbacks; 268 269 # --BEHAVIOR-- adminBeforePostCreate 270 $core->callBehavior('adminBeforePostCreate', $cur); 271 272 $return_id = $core->blog->addPost($cur); 273 274 # --BEHAVIOR-- adminAfterPostCreate 275 $core->callBehavior('adminAfterPostCreate', $cur, $return_id); 276 277 $rsp = new xmlTag('post'); 278 $rsp->id = $return_id; 279 280 $post = $core->blog->getPosts(array('post_id' => $return_id)); 281 282 $rsp->post_status = $post->post_status; 283 $rsp->post_url = $post->getURL(); 284 return $rsp; 285 } 286 287 public static function validatePostMarkup($core, $get, $post) 288 { 289 if (!isset($post['excerpt'])) { 290 throw new Exception('No entry excerpt'); 291 } 292 293 if (!isset($post['content'])) { 294 throw new Exception('No entry content'); 295 } 296 297 if (empty($post['format'])) { 298 throw new Exception('No entry format'); 299 } 300 301 if (!isset($post['lang'])) { 302 throw new Exception('No entry lang'); 303 } 304 305 $excerpt = $post['excerpt']; 306 $excerpt_xhtml = ''; 307 $content = $post['content']; 308 $content_xhtml = ''; 309 $format = $post['format']; 310 $lang = $post['lang']; 311 312 $core->blog->setPostContent(0, $format, $lang, $excerpt, $excerpt_xhtml, $content, $content_xhtml); 313 314 $rsp = new xmlTag('result'); 315 316 $v = htmlValidator::validate($excerpt_xhtml . $content_xhtml); 317 318 $rsp->valid($v['valid']); 319 $rsp->errors($v['errors']); 320 321 return $rsp; 322 } 323 324 public static function getZipMediaContent($core, $get, $post) 325 { 326 if (empty($get['id'])) { 327 throw new Exception('No media ID'); 328 } 329 330 $id = (integer) $get['id']; 331 332 if (!$core->auth->check('media,media_admin', $core->blog)) { 333 throw new Exception('Permission denied'); 334 } 335 336 try { 337 $core->media = new dcMedia($core); 338 $file = $core->media->getFile($id); 339 } catch (Exception $e) {} 340 341 if ($file === null || $file->type != 'application/zip' || !$file->editable) { 342 throw new Exception('Not a valid file'); 343 } 344 345 $rsp = new xmlTag('result'); 346 $content = $core->media->getZipContent($file); 347 348 foreach ($content as $k => $v) { 349 $rsp->file($k); 350 } 351 352 return $rsp; 353 } 354 355 public static function getMeta($core, $get) 356 { 357 $postid = !empty($get['postId']) ? $get['postId'] : null; 358 $limit = !empty($get['limit']) ? $get['limit'] : null; 359 $metaId = !empty($get['metaId']) ? $get['metaId'] : null; 360 $metaType = !empty($get['metaType']) ? $get['metaType'] : null; 361 362 $sortby = !empty($get['sortby']) ? $get['sortby'] : 'meta_type,asc'; 363 364 $rs = $core->meta->getMetadata(array( 365 'meta_type' => $metaType, 366 'limit' => $limit, 367 'meta_id' => $metaId, 368 'post_id' => $postid)); 369 $rs = $core->meta->computeMetaStats($rs); 370 371 $sortby = explode(',', $sortby); 372 $sort = $sortby[0]; 373 $order = isset($sortby[1]) ? $sortby[1] : 'asc'; 374 375 switch ($sort) { 376 case 'metaId': 377 $sort = 'meta_id_lower'; 378 break; 379 case 'count': 380 $sort = 'count'; 381 break; 382 case 'metaType': 383 $sort = 'meta_type'; 384 break; 385 default: 386 $sort = 'meta_type'; 387 } 388 389 $rs->sort($sort, $order); 390 391 $rsp = new xmlTag(); 392 393 while ($rs->fetch()) { 394 $metaTag = new xmlTag('meta'); 395 $metaTag->type = $rs->meta_type; 396 $metaTag->uri = rawurlencode($rs->meta_id); 397 $metaTag->count = $rs->count; 398 $metaTag->percent = $rs->percent; 399 $metaTag->roundpercent = $rs->roundpercent; 400 $metaTag->CDATA($rs->meta_id); 401 402 $rsp->insertNode($metaTag); 403 } 404 405 return $rsp; 406 } 407 408 public static function setPostMeta($core, $get, $post) 409 { 410 if (empty($post['postId'])) { 411 throw new Exception('No post ID'); 412 } 413 414 if (empty($post['meta']) && $post['meta'] != '0') { 415 throw new Exception('No meta'); 416 } 417 418 if (empty($post['metaType'])) { 419 throw new Exception('No meta type'); 420 } 421 422 # Get previous meta for post 423 $post_meta = $core->meta->getMetadata(array( 424 'meta_type' => $post['metaType'], 425 'post_id' => $post['postId'])); 426 $pm = array(); 427 while ($post_meta->fetch()) { 428 $pm[] = $post_meta->meta_id; 429 } 430 431 foreach ($core->meta->splitMetaValues($post['meta']) as $m) { 432 if (!in_array($m, $pm)) { 433 $core->meta->setPostMeta($post['postId'], $post['metaType'], $m); 434 } 435 } 436 437 return true; 438 } 439 440 public static function delMeta($core, $get, $post) 441 { 442 if (empty($post['postId'])) { 443 throw new Exception('No post ID'); 444 } 445 446 if (empty($post['metaId']) && $post['metaId'] != '0') { 447 throw new Exception('No meta ID'); 448 } 449 450 if (empty($post['metaType'])) { 451 throw new Exception('No meta type'); 452 } 453 454 $core->meta->delPostMeta($post['postId'], $post['metaType'], $post['metaId']); 455 456 return true; 457 } 458 459 public static function searchMeta($core, $get) 460 { 461 $q = !empty($get['q']) ? $get['q'] : null; 462 $metaType = !empty($get['metaType']) ? $get['metaType'] : null; 463 464 $sortby = !empty($get['sortby']) ? $get['sortby'] : 'meta_type,asc'; 465 466 $rs = $core->meta->getMetadata(array('meta_type' => $metaType)); 467 $rs = $core->meta->computeMetaStats($rs); 468 469 $sortby = explode(',', $sortby); 470 $sort = $sortby[0]; 471 $order = isset($sortby[1]) ? $sortby[1] : 'asc'; 472 473 switch ($sort) { 474 case 'metaId': 475 $sort = 'meta_id_lower'; 476 break; 477 case 'count': 478 $sort = 'count'; 479 break; 480 case 'metaType': 481 $sort = 'meta_type'; 482 break; 483 default: 484 $sort = 'meta_type'; 485 } 486 487 $rs->sort($sort, $order); 488 489 $rsp = new xmlTag(); 490 491 while ($rs->fetch()) { 492 if (stripos($rs->meta_id, $q) === 0) { 493 $metaTag = new xmlTag('meta'); 494 $metaTag->type = $rs->meta_type; 495 $metaTag->uri = rawurlencode($rs->meta_id); 496 $metaTag->count = $rs->count; 497 $metaTag->percent = $rs->percent; 498 $metaTag->roundpercent = $rs->roundpercent; 499 $metaTag->CDATA($rs->meta_id); 500 501 $rsp->insertNode($metaTag); 502 } 503 } 504 505 return $rsp; 506 } 507 508 public static function setSectionFold($core, $get, $post) 509 { 510 if (empty($post['section'])) { 511 throw new Exception('No section name'); 512 } 513 if ($core->auth->user_prefs->toggles === null) { 514 $core->auth->user_prefs->addWorkspace('toggles'); 515 } 516 $section = $post['section']; 517 $status = isset($post['value']) && ($post['value'] != 0); 518 if ($core->auth->user_prefs->toggles->prefExists('unfolded_sections')) { 519 $toggles = explode(',', trim($core->auth->user_prefs->toggles->unfolded_sections)); 520 } else { 521 $toggles = array(); 522 } 523 $k = array_search($section, $toggles); 524 if ($status) { 525 // true == Fold section ==> remove it from unfolded list 526 if ($k !== false) { 527 unset($toggles[$k]); 528 } 529 } else { 530 // false == unfold section ==> add it to unfolded list 531 if ($k === false) { 532 $toggles[] = $section; 533 }; 534 } 535 $core->auth->user_prefs->toggles->put('unfolded_sections', join(',', $toggles)); 536 return true; 537 } 538 539 public static function getModuleById($core, $get, $post) 540 { 541 if (empty($get['id'])) { 542 throw new Exception('No module ID'); 543 } 544 if (empty($get['list'])) { 545 throw new Exception('No list ID'); 546 } 547 548 $id = $get['id']; 549 $list = $get['list']; 550 $module = array(); 551 552 if ($list == 'plugin-activate') { 553 $modules = $core->plugins->getModules(); 554 if (empty($modules) || !isset($modules[$id])) { 555 throw new Exception('Unknow module ID'); 556 } 557 $module = $modules[$id]; 558 } elseif ($list == 'plugin-new') { 559 $store = new dcStore( 560 $core->plugins, 561 $core->blog->settings->system->store_plugin_url 562 ); 563 $store->check(); 564 565 $modules = $store->get(); 566 if (empty($modules) || !isset($modules[$id])) { 567 throw new Exception('Unknow module ID'); 568 } 569 $module = $modules[$id]; 570 } else { 571 // behavior not implemented yet 572 } 573 574 if (empty($module)) { 575 throw new Exception('Unknow module ID'); 576 } 577 578 $module = adminModulesList::sanitizeModule($id, $module); 579 580 $rsp = new xmlTag('module'); 581 $rsp->id = $id; 582 583 foreach ($module as $k => $v) { 584 $rsp->{$k}((string) $v); 585 } 586 587 return $rsp; 588 } 598 589 } -
admin/update.php
r3390 r3730 11 11 # -- END LICENSE BLOCK ----------------------------------------- 12 12 13 require dirname(__FILE__) .'/../inc/admin/prepend.php';13 require dirname(__FILE__) . '/../inc/admin/prepend.php'; 14 14 15 15 if (!defined('DC_BACKUP_PATH')) { 16 define('DC_BACKUP_PATH',DC_ROOT);16 define('DC_BACKUP_PATH', DC_ROOT); 17 17 } 18 18 … … 20 20 21 21 if (!is_readable(DC_DIGESTS)) { 22 dcPage::open(__('Dotclear update'));23 echo '<h2>Access denied</h2>';24 dcPage::close();25 exit;26 } 27 28 $updater = new dcUpdate(DC_UPDATE_URL,'dotclear',DC_UPDATE_VERSION,DC_TPL_CACHE.'/versions');29 $new_v = $updater->check(DC_VERSION, !empty($_GET['nocache']));30 $zip_file = $new_v ? DC_BACKUP_PATH.'/'.basename($updater->getFileURL()) : '';22 dcPage::open(__('Dotclear update')); 23 echo '<h2>Access denied</h2>'; 24 dcPage::close(); 25 exit; 26 } 27 28 $updater = new dcUpdate(DC_UPDATE_URL, 'dotclear', DC_UPDATE_VERSION, DC_TPL_CACHE . '/versions'); 29 $new_v = $updater->check(DC_VERSION, !empty($_GET['nocache'])); 30 $zip_file = $new_v ? DC_BACKUP_PATH . '/' . basename($updater->getFileURL()) : ''; 31 31 $version_info = $new_v ? $updater->getInfoURL() : ''; 32 32 33 33 # Hide "update me" message 34 34 if (!empty($_GET['hide_msg'])) { 35 $updater->setNotify(false);36 http::redirect('index.php');35 $updater->setNotify(false); 36 http::redirect('index.php'); 37 37 } 38 38 … … 40 40 41 41 $step = isset($_GET['step']) ? $_GET['step'] : ''; 42 $step = in_array($step, array('check','download','backup','unzip')) ? $step : '';42 $step = in_array($step, array('check', 'download', 'backup', 'unzip')) ? $step : ''; 43 43 44 44 $default_tab = !empty($_GET['tab']) ? html::escapeHTML($_GET['tab']) : 'update'; 45 45 if (!empty($_POST['backup_file'])) { 46 $default_tab = 'files';46 $default_tab = 'files'; 47 47 } 48 48 49 49 $archives = array(); 50 50 foreach (files::scanDir(DC_BACKUP_PATH) as $v) { 51 if (preg_match('/backup-([0-9A-Za-z\.-]+).zip/',$v)) {52 $archives[] = $v;53 }51 if (preg_match('/backup-([0-9A-Za-z\.-]+).zip/', $v)) { 52 $archives[] = $v; 53 } 54 54 } 55 55 if (!empty($archives)) { 56 usort($archives,"version_compare");56 usort($archives, "version_compare"); 57 57 } else { 58 $default_tab = 'update';58 $default_tab = 'update'; 59 59 } 60 60 61 61 # Revert or delete backup file 62 if (!empty($_POST['backup_file']) && in_array($_POST['backup_file'],$archives)) 63 { 64 $b_file = $_POST['backup_file']; 65 66 try 67 { 68 if (!empty($_POST['b_del'])) 69 { 70 if (!@unlink(DC_BACKUP_PATH.'/'.$b_file)) { 71 throw new Exception(sprintf(__('Unable to delete file %s'),html::escapeHTML($b_file))); 72 } 73 http::redirect($p_url.'?tab=files'); 74 } 75 76 if (!empty($_POST['b_revert'])) 77 { 78 $zip = new fileUnzip(DC_BACKUP_PATH.'/'.$b_file); 79 $zip->unzipAll(DC_BACKUP_PATH.'/'); 80 @unlink(DC_BACKUP_PATH.'/'.$b_file); 81 http::redirect($p_url.'?tab=files'); 82 } 83 } 84 catch (Exception $e) 85 { 86 $core->error->add($e->getMessage()); 87 } 62 if (!empty($_POST['backup_file']) && in_array($_POST['backup_file'], $archives)) { 63 $b_file = $_POST['backup_file']; 64 65 try 66 { 67 if (!empty($_POST['b_del'])) { 68 if (!@unlink(DC_BACKUP_PATH . '/' . $b_file)) { 69 throw new Exception(sprintf(__('Unable to delete file %s'), html::escapeHTML($b_file))); 70 } 71 http::redirect($p_url . '?tab=files'); 72 } 73 74 if (!empty($_POST['b_revert'])) { 75 $zip = new fileUnzip(DC_BACKUP_PATH . '/' . $b_file); 76 $zip->unzipAll(DC_BACKUP_PATH . '/'); 77 @unlink(DC_BACKUP_PATH . '/' . $b_file); 78 http::redirect($p_url . '?tab=files'); 79 } 80 } catch (Exception $e) { 81 $core->error->add($e->getMessage()); 82 } 88 83 } 89 84 90 85 # Upgrade process 91 if ($new_v && $step) 92 { 93 try 94 { 95 $updater->setForcedFiles('inc/digests'); 96 97 switch ($step) 98 { 99 case 'check': 100 $updater->checkIntegrity(DC_ROOT.'/inc/digests',DC_ROOT); 101 http::redirect($p_url.'?step=download'); 102 break; 103 case 'download': 104 $updater->download($zip_file); 105 if (!$updater->checkDownload($zip_file)) { 106 throw new Exception( 107 sprintf(__('Downloaded Dotclear archive seems to be corrupted. '. 108 'Try <a %s>download it</a> again.'),'href="'.$p_url.'?step=download"'). 109 ' '. 110 __('If this problem persists try to '. 111 '<a href="http://dotclear.org/download">update manually</a>.') 112 ); 113 } 114 http::redirect($p_url.'?step=backup'); 115 break; 116 case 'backup': 117 $updater->backup( 118 $zip_file, 'dotclear/inc/digests', 119 DC_ROOT, DC_ROOT.'/inc/digests', 120 DC_BACKUP_PATH.'/backup-'.DC_VERSION.'.zip' 121 ); 122 http::redirect($p_url.'?step=unzip'); 123 break; 124 case 'unzip': 125 $updater->performUpgrade( 126 $zip_file, 'dotclear/inc/digests', 'dotclear', 127 DC_ROOT, DC_ROOT.'/inc/digests' 128 ); 129 break; 130 } 131 } 132 catch (Exception $e) 133 { 134 $msg = $e->getMessage(); 135 136 if ($e->getCode() == dcUpdate::ERR_FILES_CHANGED) 137 { 138 $msg = 139 __('The following files of your Dotclear installation '. 140 'have been modified so we won\'t try to update your installation. '. 141 'Please try to <a href="http://dotclear.org/download">update manually</a>.'); 142 } 143 elseif ($e->getCode() == dcUpdate::ERR_FILES_UNREADABLE) 144 { 145 $msg = 146 sprintf(__('The following files of your Dotclear installation are not readable. '. 147 'Please fix this or try to make a backup file named %s manually.'), 148 '<strong>backup-'.DC_VERSION.'.zip</strong>'); 149 } 150 elseif ($e->getCode() == dcUpdate::ERR_FILES_UNWRITALBE) 151 { 152 $msg = 153 __('The following files of your Dotclear installation cannot be written. '. 154 'Please fix this or try to <a href="http://dotclear.org/download">update manually</a>.'); 155 } 156 157 if (isset($e->bad_files)) { 158 $msg .= 159 '<ul><li><strong>'. 160 implode('</strong></li><li><strong>',$e->bad_files). 161 '</strong></li></ul>'; 162 } 163 164 $core->error->add($msg); 165 166 $core->callBehavior('adminDCUpdateException',$e); 167 } 86 if ($new_v && $step) { 87 try 88 { 89 $updater->setForcedFiles('inc/digests'); 90 91 switch ($step) { 92 case 'check': 93 $updater->checkIntegrity(DC_ROOT . '/inc/digests', DC_ROOT); 94 http::redirect($p_url . '?step=download'); 95 break; 96 case 'download': 97 $updater->download($zip_file); 98 if (!$updater->checkDownload($zip_file)) { 99 throw new Exception( 100 sprintf(__('Downloaded Dotclear archive seems to be corrupted. ' . 101 'Try <a %s>download it</a> again.'), 'href="' . $p_url . '?step=download"') . 102 ' ' . 103 __('If this problem persists try to ' . 104 '<a href="http://dotclear.org/download">update manually</a>.') 105 ); 106 } 107 http::redirect($p_url . '?step=backup'); 108 break; 109 case 'backup': 110 $updater->backup( 111 $zip_file, 'dotclear/inc/digests', 112 DC_ROOT, DC_ROOT . '/inc/digests', 113 DC_BACKUP_PATH . '/backup-' . DC_VERSION . '.zip' 114 ); 115 http::redirect($p_url . '?step=unzip'); 116 break; 117 case 'unzip': 118 $updater->performUpgrade( 119 $zip_file, 'dotclear/inc/digests', 'dotclear', 120 DC_ROOT, DC_ROOT . '/inc/digests' 121 ); 122 break; 123 } 124 } catch (Exception $e) { 125 $msg = $e->getMessage(); 126 127 if ($e->getCode() == dcUpdate::ERR_FILES_CHANGED) { 128 $msg = 129 __('The following files of your Dotclear installation ' . 130 'have been modified so we won\'t try to update your installation. ' . 131 'Please try to <a href="http://dotclear.org/download">update manually</a>.'); 132 } elseif ($e->getCode() == dcUpdate::ERR_FILES_UNREADABLE) { 133 $msg = 134 sprintf(__('The following files of your Dotclear installation are not readable. ' . 135 'Please fix this or try to make a backup file named %s manually.'), 136 '<strong>backup-' . DC_VERSION . '.zip</strong>'); 137 } elseif ($e->getCode() == dcUpdate::ERR_FILES_UNWRITALBE) { 138 $msg = 139 __('The following files of your Dotclear installation cannot be written. ' . 140 'Please fix this or try to <a href="http://dotclear.org/download">update manually</a>.'); 141 } 142 143 if (isset($e->bad_files)) { 144 $msg .= 145 '<ul><li><strong>' . 146 implode('</strong></li><li><strong>', $e->bad_files) . 147 '</strong></li></ul>'; 148 } 149 150 $core->error->add($msg); 151 152 $core->callBehavior('adminDCUpdateException', $e); 153 } 168 154 } 169 155 … … 171 157 -------------------------------------------------------- */ 172 158 dcPage::open(__('Dotclear update'), 173 (!$step ?174 dcPage::jsPageTabs($default_tab).175 dcPage::jsLoad('js/_update.js')176 : ''),177 dcPage::breadcrumb(178 array(179 __('System')=> '',180 __('Dotclear update') => ''181 ))159 (!$step ? 160 dcPage::jsPageTabs($default_tab) . 161 dcPage::jsLoad('js/_update.js') 162 : ''), 163 dcPage::breadcrumb( 164 array( 165 __('System') => '', 166 __('Dotclear update') => '' 167 )) 182 168 ); 183 169 184 170 if (!$core->error->flag()) { 185 if (!empty($_GET['nocache'])) { 186 dcPage::success(__('Manual checking of update done successfully.')); 187 } 188 } 189 190 if (!$step) 191 { 192 echo '<div class="multi-part" id="update" title="'.__('Dotclear update').'">'; 193 if (empty($new_v)) 194 { 195 echo '<p><strong>'.__('No newer Dotclear version available.').'</strong></p>'. 196 '<form action="'.$p_url.'" method="get">'. 197 '<p><input type="hidden" name="nocache" value="1" />'. 198 '<input type="submit" value="'.__('Force checking update Dotclear').'" /></p>'. 199 '</form>'; 200 } 201 else 202 { 203 echo 204 '<p class="static-msg">'.sprintf(__('Dotclear %s is available.'),$new_v). 205 ($version_info ? ' <a href="'.$version_info.'" class="outgoing" title="'.__('Information about this version').'">('. 206 __('Information about this version').') <img src="images/outgoing.png" alt=""/></a>' : ''). 207 '</p>'; 208 if (version_compare(phpversion(),$updater->getPHPVersion()) < 0) { 209 echo 210 '<p class="warning-msg">'.sprintf(__('PHP version is %s (%s or earlier needed).'),phpversion(),$updater->getPHPVersion()).'</p>'; 211 } else { 212 echo 213 '<p>'.__('To upgrade your Dotclear installation simply click on the following button. '. 214 'A backup file of your current installation will be created in your root directory.').'</p>'. 215 '<form action="'.$p_url.'" method="get">'. 216 '<p><input type="hidden" name="step" value="check" />'. 217 '<input type="submit" value="'.__('Update Dotclear').'" /></p>'. 218 '</form>'; 219 } 220 } 221 echo '</div>'; 222 223 if (!empty($archives)) 224 { 225 echo '<div class="multi-part" id="files" title="'.__('Manage backup files').'">'; 226 227 echo 228 '<h3>'.__('Update backup files').'</h3>'. 229 '<p>'.__('The following files are backups of previously updates. '. 230 'You can revert your previous installation or delete theses files.').'</p>'; 231 232 echo '<form action="'.$p_url.'" method="post">'; 233 foreach ($archives as $v) { 234 echo 235 '<p><label class="classic">'.form::radio(array('backup_file'),html::escapeHTML($v)).' '. 236 html::escapeHTML($v).'</label></p>'; 237 } 238 239 echo 240 '<p><strong>'.__('Please note that reverting your Dotclear version may have some '. 241 'unwanted side-effects. Consider reverting only if you experience strong issues with this new version.').'</strong> '. 242 sprintf(__('You should not revert to version prior to last one (%s).'),end($archives)). 243 '</p>'. 244 '<p><input type="submit" class="delete" name="b_del" value="'.__('Delete selected file').'" /> '. 245 '<input type="submit" name="b_revert" value="'.__('Revert to selected file').'" />'. 246 $core->formNonce().'</p>'. 247 '</form>'; 248 249 echo '</div>'; 250 } 251 } 252 elseif ($step == 'unzip' && !$core->error->flag()) 253 { 254 echo 255 '<p class="message">'. 256 __("Congratulations, you're one click away from the end of the update."). 257 ' <strong><a href="index.php?logout=1">'.__('Finish the update.').'</a></strong>'. 258 '</p>'; 171 if (!empty($_GET['nocache'])) { 172 dcPage::success(__('Manual checking of update done successfully.')); 173 } 174 } 175 176 if (!$step) { 177 echo '<div class="multi-part" id="update" title="' . __('Dotclear update') . '">'; 178 if (empty($new_v)) { 179 echo '<p><strong>' . __('No newer Dotclear version available.') . '</strong></p>' . 180 '<form action="' . $p_url . '" method="get">' . 181 '<p><input type="hidden" name="nocache" value="1" />' . 182 '<input type="submit" value="' . __('Force checking update Dotclear') . '" /></p>' . 183 '</form>'; 184 } else { 185 echo 186 '<p class="static-msg">' . sprintf(__('Dotclear %s is available.'), $new_v) . 187 ($version_info ? ' <a href="' . $version_info . '" class="outgoing" title="' . __('Information about this version') . '">(' . 188 __('Information about this version') . ') <img src="images/outgoing.png" alt=""/></a>' : '') . 189 '</p>'; 190 if (version_compare(phpversion(), $updater->getPHPVersion()) < 0) { 191 echo 192 '<p class="warning-msg">' . sprintf(__('PHP version is %s (%s or earlier needed).'), phpversion(), $updater->getPHPVersion()) . '</p>'; 193 } else { 194 echo 195 '<p>' . __('To upgrade your Dotclear installation simply click on the following button. ' . 196 'A backup file of your current installation will be created in your root directory.') . '</p>' . 197 '<form action="' . $p_url . '" method="get">' . 198 '<p><input type="hidden" name="step" value="check" />' . 199 '<input type="submit" value="' . __('Update Dotclear') . '" /></p>' . 200 '</form>'; 201 } 202 } 203 echo '</div>'; 204 205 if (!empty($archives)) { 206 echo '<div class="multi-part" id="files" title="' . __('Manage backup files') . '">'; 207 208 echo 209 '<h3>' . __('Update backup files') . '</h3>' . 210 '<p>' . __('The following files are backups of previously updates. ' . 211 'You can revert your previous installation or delete theses files.') . '</p>'; 212 213 echo '<form action="' . $p_url . '" method="post">'; 214 foreach ($archives as $v) { 215 echo 216 '<p><label class="classic">' . form::radio(array('backup_file'), html::escapeHTML($v)) . ' ' . 217 html::escapeHTML($v) . '</label></p>'; 218 } 219 220 echo 221 '<p><strong>' . __('Please note that reverting your Dotclear version may have some ' . 222 'unwanted side-effects. Consider reverting only if you experience strong issues with this new version.') . '</strong> ' . 223 sprintf(__('You should not revert to version prior to last one (%s).'), end($archives)) . 224 '</p>' . 225 '<p><input type="submit" class="delete" name="b_del" value="' . __('Delete selected file') . '" /> ' . 226 '<input type="submit" name="b_revert" value="' . __('Revert to selected file') . '" />' . 227 $core->formNonce() . '</p>' . 228 '</form>'; 229 230 echo '</div>'; 231 } 232 } elseif ($step == 'unzip' && !$core->error->flag()) { 233 echo 234 '<p class="message">' . 235 __("Congratulations, you're one click away from the end of the update.") . 236 ' <strong><a href="index.php?logout=1">' . __('Finish the update.') . '</a></strong>' . 237 '</p>'; 259 238 } 260 239 -
admin/user.php
r3725 r3730 320 320 '<p><label for="user_edit_size">' . __('Entry edit field height:') . '</label> ' . 321 321 form::number('user_edit_size', 10, 999, (integer) $user_options['edit_size']) . 322 '</p>';322 '</p>'; 323 323 324 324 # --BEHAVIOR-- adminUserForm -
admin/xmlrpc.php
r2730 r3730 11 11 # -- END LICENSE BLOCK ----------------------------------------- 12 12 13 require dirname(__FILE__) .'/../inc/prepend.php';13 require dirname(__FILE__) . '/../inc/prepend.php'; 14 14 15 15 if (isset($_SERVER['PATH_INFO'])) { 16 $blog_id = trim($_SERVER['PATH_INFO']);17 $blog_id = preg_replace('#^/#','',$blog_id);16 $blog_id = trim($_SERVER['PATH_INFO']); 17 $blog_id = preg_replace('#^/#', '', $blog_id); 18 18 } elseif (!empty($_GET['b'])) { 19 $blog_id = $_GET['b'];19 $blog_id = $_GET['b']; 20 20 } 21 21 22 22 if (empty($blog_id)) { 23 header('Content-Type: text/plain');24 http::head(412);25 echo 'No blog ID given';26 exit;23 header('Content-Type: text/plain'); 24 http::head(412); 25 echo 'No blog ID given'; 26 exit; 27 27 } 28 28 … … 34 34 35 35 # Start XML-RPC server 36 $server = new dcXmlRpc($core, $blog_id);36 $server = new dcXmlRpc($core, $blog_id); 37 37 $server->serve();
Note: See TracChangeset
for help on using the changeset viewer.
