Current oav website
BIN
.tmp/Archive.zip
Normal file
1
.tmp/index.html
Normal file
@ -0,0 +1 @@
|
||||
Beuuuuuaaaaa
|
||||
BIN
_blank.gif
Normal file
|
After Width: | Height: | Size: 42 B |
3
blog/index.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
header("Location: /dotclear");
|
||||
?>
|
||||
162
css/base.css
Normal file
@ -0,0 +1,162 @@
|
||||
body { margin:0px; background-color:#fff; height:100% }
|
||||
html { height:100% }
|
||||
img { margin:0px; border-style:none }
|
||||
button { margin:0px; border-style:none; padding:0px; background-color:transparent; vertical-align:top }
|
||||
p:first-child { margin-top:0px }
|
||||
table { empty-cells:hide }
|
||||
em { font-style:italic }
|
||||
h1 { font-size:18px }
|
||||
h1:first-child { margin-top:0px }
|
||||
strong { font-weight:bold }
|
||||
.lapage {
|
||||
color:#585769;
|
||||
font-family:arial, helvetica;
|
||||
text-align:center;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.menuhaut {
|
||||
color:#000000;
|
||||
font-family:arial, helvetica;
|
||||
text-align:right;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.menubas {
|
||||
color:#000000;
|
||||
font-family:arial, helvetica;
|
||||
text-align:right;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.menuon {
|
||||
color:#585769;
|
||||
font-family:arial, helvetica;
|
||||
text-align:right;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.menuoff {
|
||||
color:#828098;
|
||||
font-family:arial, helvetica;
|
||||
text-align:right;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.textetitre {
|
||||
color:#eb6e08;
|
||||
font-family:arial, helvetica;
|
||||
font-weight:bold;
|
||||
text-align:left;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.texte {
|
||||
color:#585769;
|
||||
font-family:arial, helvetica;
|
||||
text-align:center;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.letrait {
|
||||
position:absolute;
|
||||
left:300px;
|
||||
top:0px;
|
||||
width:39px;
|
||||
height:768px;
|
||||
z-index:1;
|
||||
}
|
||||
|
||||
.logo {
|
||||
position:absolute;
|
||||
left:38px;
|
||||
top:338px;
|
||||
width:262px;
|
||||
height:92px;
|
||||
z-index:2;
|
||||
}
|
||||
|
||||
.illustration {
|
||||
position:absolute;
|
||||
left:699px;
|
||||
top:0px;
|
||||
width:325px;
|
||||
height:768px;
|
||||
z-index:3;
|
||||
}
|
||||
.divmenuhaut {
|
||||
position:absolute;
|
||||
left:38px;
|
||||
top:0px;
|
||||
width:262px;
|
||||
height:338px;
|
||||
z-index:4;i
|
||||
padding-top: 38px;
|
||||
overflow:visible;
|
||||
line-height: 50px;
|
||||
}
|
||||
|
||||
.divmenubas {
|
||||
position:absolute;
|
||||
left:38px;
|
||||
top:430px;
|
||||
width:262px;
|
||||
height:338px;
|
||||
z-index:5;
|
||||
padding-top: 10px;
|
||||
overflow:visible;
|
||||
line-height: 50px;
|
||||
}
|
||||
|
||||
.textebox {
|
||||
position:absolute;
|
||||
left:339px;
|
||||
top:0px;
|
||||
zzzwidth:360px;
|
||||
width:685px;
|
||||
zzheight:768px;
|
||||
z-index:6;
|
||||
padding-top: 38px;
|
||||
overflow:visible;
|
||||
}
|
||||
|
||||
.textebox li {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.textebox a {
|
||||
color:#eb6e08;
|
||||
font-family:arial, helvetica;
|
||||
font-size: 13px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.textebox a:hover {
|
||||
color:#eb6e08;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.menu {
|
||||
list-style-type: none;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.menu li {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.menu a {
|
||||
font-family:arial, helvetica;
|
||||
text-align:right;
|
||||
font-size: 20px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.menu a:hover {
|
||||
color:#585769;
|
||||
font-family:arial, helvetica;
|
||||
text-align:right;
|
||||
font-size: 20px;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
BIN
cv/Xavier_Beaudouin_2005.doc
Normal file
BIN
cv/Xavier_Beaudouin_2005.pdf
Normal file
BIN
cv/Xavier_Beaudouin_2006.doc
Normal file
BIN
cv/Xavier_Beaudouin_2006.pdf
Normal file
BIN
cv/Xavier_Beaudouin_2008.odt
Normal file
BIN
cv/Xavier_Beaudouin_2008.pdf
Normal file
BIN
cv/Xavier_Beaudouin_2011.docx
Normal file
BIN
cv/Xavier_Beaudouin_2011.pdf
Normal file
BIN
cv/Xavier_Beaudouin_2011_EN_2.pdf
Normal file
BIN
cv/Xavier_Beaudouin_2012.pdf
Normal file
BIN
cv/Xavier_Beaudouin_2013.pdf
Normal file
15
cv/index.php
Normal file
@ -0,0 +1,15 @@
|
||||
<!-- $Id: index.php,v 1.2 2009/09/18 14:20:03 kiwi Exp $ -->
|
||||
<?php
|
||||
require_once("../include/function.inc.php");
|
||||
page("CV");
|
||||
?>
|
||||
<p class="textetitre">CV / Resume</p>
|
||||
<p class="texte">
|
||||
Here is my CV or Resume. Currently working in Luxembourg at <a href="https://hotcity.lu">Hotcity SA</a>.
|
||||
<ul>
|
||||
<li><a href="https://github.com/xbeaudouin/cv/raw/master/xavier/xbeaudouin.pdf">English</a> PDF on my Github</li>
|
||||
</ul>
|
||||
</p>
|
||||
<?php
|
||||
finpage();
|
||||
?>
|
||||
BIN
cv/xb-motivation.doc
Normal file
BIN
cv/xbeaudouin.pdf
Normal file
932
dotclear._no/CHANGELOG
Normal file
@ -0,0 +1,932 @@
|
||||
Dotclear 2.16 - 2020-03-13
|
||||
===========================================================
|
||||
* 🐘 PHP 5.6+ is required, PHP 7.4 compliance
|
||||
* 🛡 Security: all requests from/to Dotclear and DotAddict servers use now HTTPS
|
||||
* jQuery upgraded to 3.4.1, older version will be removed, jQuery not anymore requested for "Remember me" feature
|
||||
* New "static" mode for home page
|
||||
* Media description may now be updated
|
||||
* Add <i [lang="…"]>…</i> support to Dotclear wiki, syntax: ££text[|lang]££
|
||||
* Lib: Update Codemirror to 5.52.0
|
||||
* Lib: Update CKEditor to 4.14.0
|
||||
* Lib: Clearbricks now supports MySQL 8+
|
||||
* 🐛 → Various bugs, a11y concerns and typos fixed
|
||||
* 🌼 → Some locales and cosmetic adjustments
|
||||
|
||||
Dotclear 2.15.3 - 2019-11-28
|
||||
===========================================================
|
||||
* Fix: Avoid weird side-effect of JS minifier
|
||||
* Fix: insertion of default type media (non image/audio/video) in XHTML entries
|
||||
* Fix: Cope with old themes for 'remember me' string defined in JS
|
||||
|
||||
Dotclear 2.15.2 - 2019-10-01
|
||||
===========================================================
|
||||
* Fix: Ajax saving of files in theme editor when using codemirror
|
||||
* Fix: Video insertion with CKEditor or LegacyEditor
|
||||
* Fix: Badge position for dashboard modules counters
|
||||
|
||||
Dotclear 2.15.1 - 2019-08-29
|
||||
===========================================================
|
||||
* Fix: SQL request for CSP unsafe-inline setting
|
||||
* Fix: CKEditor configuration for foreign language (unabled to save post modifications)
|
||||
|
||||
Dotclear 2.15 - 2019-08-13
|
||||
===========================================================
|
||||
* 🐘 PHP 5.6+ is required, PHP 7.3 compliance
|
||||
* Add drag'n'drop sorting system for dashboard blocks
|
||||
* Backend context is preserved on switching blog (as far as possible, depending on user's grants)
|
||||
* No more inline javascript, default/install CSP directive modified accordingly
|
||||
* Add settings (in maintenance plugin) for CSP system
|
||||
* Set correct lang attribute (useful for browser/editor spelling) for content (post/page) depending on entry setting, and CK editor UI in user language
|
||||
* Add spellcheck="true" attribute on input/textarea
|
||||
* Refactoring of notices/messages system on backend
|
||||
* Add undo/redo buttons to CKEditor toolbar
|
||||
* Add title/legend reminder on media popup insertion (1st tab)
|
||||
* Add font loading capabilities for ?pf= system - plugin are now able to load css fonts
|
||||
* Add WebP image format support to Dotclear (may depends on your server PHP capabilities)
|
||||
* Add <sub>…</sub> support in Dotclear wiki, syntax : _indice_
|
||||
* Template system: Allow ?sub for category/categories attributes of tpl:EntryIf, and for url/urls attributes of tpl:CategoryIf
|
||||
* Responsive tables/lists (posts, pages, users, …)
|
||||
* Spams preview (administrative board) now shows HTML code rather than interpreted content
|
||||
* Fix: port used behind reverse proxy (Clearbricks)
|
||||
* Lib: Update Codemirror to 5.48.0
|
||||
* Lib: Update CKEditor to 4.12.0
|
||||
* 🗑 → No more flash players (flv,mp3)
|
||||
* 🐛 → Various bugs, a11y concerns and typos fixed
|
||||
* 🌼 → Some locales and cosmetic adjustments
|
||||
|
||||
Dotclear 2.14.3 - 2018-09-26
|
||||
===========================================================
|
||||
* 🛡 Security: Avoid XML upload in media manager
|
||||
* Fix: Upgrade modification for media_exclusion default setting
|
||||
* Fix: cope with PHP.ini setting memory_limit set to -1 (unlimited)
|
||||
|
||||
Dotclear 2.14.2 - 2018-09-04
|
||||
===========================================================
|
||||
* 🛡 Security: Authenticated cross-site scripting (XSS) was possible due to the .ahtml (or .bhtml, .chtml, …) file extension being allowed in the media manager. Thank's Josiah Pierce for report (CVE-2018-16358)
|
||||
* 🛡 Security: Unregister phar wrapper in order to avoid PHP Phar extension vulerability
|
||||
* Fix: Enter key in some input fields were not redirect to the parent form
|
||||
* Fix: Unable to save modified theme's files in theme editor, when Codemirror is used
|
||||
* Fix: Back to the original global_filters() template function (will be rewritten in the next 2.15)
|
||||
|
||||
Dotclear 2.14.1 - 2018-08-17
|
||||
===========================================================
|
||||
* 🐘 PHP 5.6+ is required - PHP 5.5 is buggy with the 2.14 release
|
||||
* Fix: install wizzard was broken
|
||||
* Fix: smallest admin font size was set when saving user prefs
|
||||
* Fix: minifying JS scripts may cause problems with regular expressions
|
||||
* Fix: empty JS var was set for syntax coloration if disabled
|
||||
|
||||
Dotclear 2.14 - 2018-08-13
|
||||
===========================================================
|
||||
* 🛡 Security: Fix potential reflective XSS, thank's Zekvan Arslan for report (via Daniel Bishtawi from https://www.netsparker.com/)
|
||||
* 🐘 PHP 7.2 compliance
|
||||
* Use specialized fields whenever it's possible (email, …)
|
||||
* Add definition list capabilities (dl, dt, dd) to wiki (= <term>, : <definition>)
|
||||
* Add <sup>…</sup> support in wiki, syntax : ^exponant^
|
||||
* Add syntax property/method to dblayer driver
|
||||
* Replace some js oriented background fading by CSS3 animation
|
||||
* Enhance some visual focus indicators
|
||||
* Enhance key event management in popup (Esc, Enter, …)
|
||||
* Template filters may now be extended (or modified) by 3rd party plugins (via behaviors)
|
||||
* PSR-2 code formatting as far as possible (work in progress)
|
||||
* Add two new ways to order tags (by oldest or newest associated post publication date)
|
||||
* Update Codemirror to 5.38.0
|
||||
* Update CKEditor to 4.9.2
|
||||
* Update jQuery migrate plugin to 1.4.1
|
||||
* Update jQuery UI (custom) 1.12.1
|
||||
* Add a dark mode (via user preferences) for administration, CSS refactoring
|
||||
* Animate some counters on dashboard icons (nb of comments, spam comments and posts)
|
||||
* 🐛 → Various bugs and typos fixed
|
||||
* 🌼 → Some locales and cosmetic adjustments
|
||||
|
||||
Dotclear 2.13.1 - 2018-01-27
|
||||
===========================================================
|
||||
* Fix: Weird behaviour of theme editor when typing any of "t", "r", "u" and "e" characters
|
||||
* Fix: Unable to save an entry with dcLegacyEditor in XHTML mode, visual pane
|
||||
|
||||
Dotclear 2.13 - 2018-01-13
|
||||
===========================================================
|
||||
* 🐘 PHP 5.5+ is required
|
||||
* 🛡 Security: New password management system (including silent migration)
|
||||
* 🛡 Security: Add Referrer-Policy header in admin pages
|
||||
* 🛡 Security: Fix potential XSS - thank's Trí Chim Trích for report
|
||||
* Dotclear news are now displayed in async way by js
|
||||
* Dotclear core update check is now done by async js - a forced check may still be done on <admin>/update.php page
|
||||
* Add utf8mb4 driver (MySQL server 5.7.7+)
|
||||
* Add target="blank" option in simpleMenu
|
||||
* Update CKEditor from 4.6.2 to 4.7.3
|
||||
* Update CodeMirror from 5.25.1 to 5.32.1
|
||||
* Add required attribute for mandatory fields
|
||||
* Fix: Avoid horizontal scrolling table when longest comment's usernames in list of comments
|
||||
* Fix: Cope with MySQLi connection via socket
|
||||
* Fix: Error messages markup and styling
|
||||
* Fix: Set caret at the end of the inserted thing (img, url, blockquote, …) in Legacy editor if current selection is empty
|
||||
* Fix: Cope with query part only in SimpleMenu URLs
|
||||
* 🐛 → Various bugs and typos fixed
|
||||
* 🌼 → Some locales and cosmetic adjustments
|
||||
|
||||
Dotclear 2.12.2 - merged in 2.13
|
||||
===========================================================
|
||||
* Fix: lang attribute was missing on entry alone contexts for currywurst and dotty templatesets
|
||||
* Fix: Add http:// protocol before media.dotaddict.org for csp_admin_img
|
||||
* Fix: tpl:sysIf blog_lang generated code
|
||||
* Fix: Duplicate auto-generated URI (entries)
|
||||
* Fix: Do not use border and background on select to use the system aspect of them in Firefox.
|
||||
* Fix: For select element, target Safari to cope with font-size select/option problem.
|
||||
* Fix: Error messages styling
|
||||
|
||||
Dotclear 2.12.1 - 2017-08-13
|
||||
===========================================================
|
||||
* Fix: 3rd party filters for template tags (std filters are not more modifiable)
|
||||
* Fix: Media filename are now used without modification for media title on upload (advanced mode)
|
||||
|
||||
Dotclear 2.12 - 2017-07-27
|
||||
===========================================================
|
||||
* 🛡 Security: Fix potential XSS
|
||||
* 🛡 Security: Enforce uniqness of the recovery key
|
||||
* 🛡 Security: Switch hash method from sha1 to sha512 (new installation only)
|
||||
* Two new values for base font size (37.5% and 87.5%)
|
||||
* Adaptive admin font size is now optional
|
||||
* Reduce base font size on very small devices
|
||||
* Refactor some functions to closures
|
||||
* No CSP directives in safe mode
|
||||
* Add current blog domain for script and style CSP directives
|
||||
* Backlinks:
|
||||
* Retrieving ping URLs, let trackback first, then pingback, then finally webmention
|
||||
* Get source post content to compose webmention excerpt and retrieve title
|
||||
* Use source post title as blog name if this one is unknown (Anonymous blog is used if neither title nor blog name are known)
|
||||
* Datepicker's look refreshed
|
||||
* Allow 3rd party additional headers (URL handler)
|
||||
* Dublin core metadata removed
|
||||
* Using theme\<theme_name> namespace for _public.php and _prepend.php, in order to simplify theme copy and hack
|
||||
* Temporary password will have to be changed at first login (after resetting password)
|
||||
* Add ukrainian language
|
||||
* French help updated for theme editor
|
||||
* Add an option to disable Dotclear updates check (super-admin only)
|
||||
* Fix: Blogs’ admin (ie not super-admin) got back their blogs’ list but only super-admin may do actions
|
||||
* Fix: Post/page edition layout on different screen sizes
|
||||
* Fix: x-frame-options URL in admin
|
||||
* Fix: Cope with several copies of a same smiley in content
|
||||
* Fix: Allow 3rd party filters for template tags
|
||||
* Fix: Use getURLFor instead of old getBase function for breadcrumb
|
||||
* Fix: Give mysql/mysqli driver choice for DC 1.2 import
|
||||
* Clearbricks lib update from 0.9 to 1.0
|
||||
* jQuery lib update from 2.2.0 to 2.2.4 (last release of jQuery 2.n branch)
|
||||
* CKEditor lib update from 4.6.1 to 4.6.2
|
||||
* CodeMirror lib update from 5.15.3 to 5.25.1
|
||||
* 🐛 → Various bugs and typos fixed
|
||||
* 🌼 → Some locales and cosmetic adjustments
|
||||
* 📣 Warning: Next major release (2.13) will require PHP 5.5+
|
||||
|
||||
Dotclear 2.11.2 - 2016-12-29
|
||||
===========================================================
|
||||
* Fix: Ensure compatibility with old version of PHP (5.3, 5.4)
|
||||
* Fix: New path of CSP report for maintenance deletion task
|
||||
* Fix: Broken entry preview
|
||||
* Fix: Avoid outgoing link on images in media manager
|
||||
* 🌼 → Do not include empty div as it disrupts CSS flexbox system
|
||||
|
||||
Dotclear 2.11.1 - 2016-12-28
|
||||
===========================================================
|
||||
* Fix: admin menu not visible and some plugin admin not accessible with PHP < 5.5
|
||||
|
||||
Dotclear 2.11 - 2016-12-28
|
||||
===========================================================
|
||||
* 🐘 PHP 5.3+ is required
|
||||
* 🛡 Security : Prevents XSS injection in media title, thanks smarterbitbybit for report
|
||||
* Cope with locale for sorting order if possible (work in progress)
|
||||
* Rich-text-editor (xhtml) may be disabled for Blog/Category description, widget's textareas, …
|
||||
* Add direct access to module's settings from plugins management page (depends on _define.php of modules)
|
||||
* Menus (except favorites) are now lexically sorted (except "new post" item)
|
||||
* Add Entry date as sort order in comments list
|
||||
* Switch admin CSS to Sass/Compass (work in progress)
|
||||
* Add 'l' and 'm' accesskey for editor toolbars, respectively for 'insert link' and 'select media' buttons
|
||||
* Add new categories attribute to EntryIf template tag
|
||||
* Remove Dublin-core metadata from <head> in template-sets
|
||||
* ToolMan (js) not more used, thank's Tim Taylor for all this years together!
|
||||
* Soft redesign of administration pages using responsive font-size and OS system fonts (IE 10+)
|
||||
* Add a user preference to hide additional/secondary information
|
||||
* Add actions on blog list, new sort order: blog status
|
||||
* Update CKEditor to 4.6.1
|
||||
* Open trackbacks with behaviors and add basic Webmention support
|
||||
* Add First Publication mecanism and an option to auto-ping when fired
|
||||
* Berlin theme is now based on Dotty template-set
|
||||
* Move advanced and plugins blog’s prefs in two separate foldable sections
|
||||
* Add legend and title insertion option for image insertion in entry
|
||||
* Some notices and messages may be hidden
|
||||
* Add urls attribute to CategoryIf template tag
|
||||
* CSP: Move admin CSP admin/csp_report.txt to DC_VAR/csp/csp_report.json
|
||||
* CSP: Violations are now stored only once in report if repeated
|
||||
* a11y: Remove empty link (href=#) from admin
|
||||
* Fix: Proxies may use standard HTTP(S) ports and SSL may now run through a proxy
|
||||
* Fix: Prevents precondition failed during activated theme update
|
||||
* 🐛 → Various bugs and typos fixed
|
||||
* 🌼 → A lot of locales and cosmetic adjustments
|
||||
* 🚽 → Housecleaning of no more used scripts, images, resources, IE 9- :-)
|
||||
|
||||
Dotclear 2.10.4 - 2016-11-02
|
||||
===========================================================
|
||||
* PostgreSQL < 9.1 fix
|
||||
|
||||
Dotclear 2.10.3 - 2016-11-01
|
||||
===========================================================
|
||||
* Security: Fix CVE-2016-7903: Password Reset Address Spoof — Thank's Hongkun Zeng for report
|
||||
* Security: Fix CVE-2016-7902: Media Manager, unrestricted File Upload — Thank's Hongkun Zeng for report
|
||||
* CSP: Cope with external sources used in editor's iframe to preview public external content
|
||||
* Fix: Cope with post.post_position field during flat import
|
||||
* Fix: Prevents precondition failed during currently activated theme update
|
||||
* Fix: Remove unecessary header (cope by dotclear) in page plugin
|
||||
* Fix: Let some proxies playing with standard http and https ports
|
||||
* Fix: Let SSL runs through a proxy, it may be ok, sometimes
|
||||
* 🐛 → Various bugs and typos fixed
|
||||
|
||||
Dotclear 2.10.2 - 2016-08-17
|
||||
===========================================================
|
||||
* Update fails with PostgreSQL db support → fixed
|
||||
|
||||
Dotclear 2.10.1 - 2016-08-15
|
||||
===========================================================
|
||||
* CSP (Content-Security-Policies) :
|
||||
* Fix default directive for new installation
|
||||
* Cope with media public URL for media manager
|
||||
* Cope with blog public URL for post/page preview
|
||||
* Codemirror lib is now packed as the other Javascript lib are
|
||||
|
||||
Dotclear 2.10 - 2016-08-13
|
||||
===========================================================
|
||||
* Security: Prevents .htaccess upload, thanks wiswat
|
||||
* Security: Prevents download of a zip media folder outside root media folder, thanks wiswat
|
||||
* Security: Prevents sort of SSRF/XSPA vulnerability in feed import, thanks wiswat
|
||||
* Security: Prevents reflected XSS in meda manager, thanks Chen Ruiqi
|
||||
* Security: Fix somes vulnerabilities in blogroll plugin, thanks Onur Yılmaz - Netsparker (https://www.netsparker.com)
|
||||
* Fix mix-content preview
|
||||
* Pure CSS3 sticky footer for admin pages (aka « footer de merde »)
|
||||
* Add missing breadcrumb styles for blowup theme
|
||||
* Currently logged super-admin may now change it's id wihtout loosing access at next login
|
||||
* The favorites icons may now be hidden from dashboard in user preferences
|
||||
* Number of posts/pages/comments are now displayed at top of lists, including quick filters depending on their status
|
||||
* Search widget has now a placeholder option (HTML5 only)
|
||||
* Add Apache 2.4+ directives in .htaccess
|
||||
* New favorites media folders (displayed at the top of recent folder list) in media manager
|
||||
* New pure HTML5 template set named dotty cloned from currywurst templateset
|
||||
* Codemirror lib updated (2.35.0 → 5.15.2) and moved to core:
|
||||
* 40+ Codemirror themes are available — set in user preferences
|
||||
* Fullscreen mode has been added (F11 switching key)
|
||||
* 3rd party plugins may now load and run it with dcPage::jsLoadCodeMirror() and dcPage::jsRunCodeMirror(), see themeEditor plugin for example
|
||||
* New mark button for legacy editor (HTML5 only)
|
||||
* New with_category attribute for tpl:Entries
|
||||
* Add a /var directory:
|
||||
* Set with DC_VAR constant in inc/config.php
|
||||
* Admin URL of a var file should be retrieve with dcPage::getVF()
|
||||
* Public URL of a var file should be retrieve with dcBlog::getVF()
|
||||
* 3rd party plugins should create their own folder inside /var (aka DC_VAR) to keep it correctly organized
|
||||
* Emails and web site have been added to the comments filters' list
|
||||
* Some columns for posts and pages lists are now optional — set in user preferences
|
||||
* Add Post URL sample in blog parameters
|
||||
* CKEditor lib update (4.5.8 → 4.6.0)
|
||||
* Wiki syntax: new ") <text>" mark to generate aside blocks
|
||||
* CSP (Content Security Policies) have been implemented on admin pages:
|
||||
* settings may be adjusted in system settings / about:config → system (see csp_admin… values)
|
||||
* violation reports will be stored in admin/csp_report.txt (PHP 5.4+ only)
|
||||
* new behaviour adminPageHTTPHeaderCSP may be used by 3rd party to adjust CSP directives
|
||||
* New behaviour adminPageHTTPheaders
|
||||
* New "Go Top" button displayed for long admin pages
|
||||
* 🐛 → Various bugs and typos fixed
|
||||
* 🌼 → Some locales and cosmetic adjustments
|
||||
|
||||
Dotclear 2.9.1 - 2016-03-27
|
||||
===========================================================
|
||||
* Security: Add shtml extension to default media exclusion extension control, thanks Nitin Venkatesh for report
|
||||
* Changing theme is now allowed even with read-only theme folder
|
||||
* Audio media are not more preloaded in media manager pages
|
||||
* Array settings/prefs are stored with 'array' type rather than 'string'
|
||||
* 🐛 → Various bug fixes
|
||||
* 🌼 → Some cosmetic adjustments
|
||||
|
||||
Dotclear 2.9 - 2016-02-29
|
||||
===========================================================
|
||||
* Additionnal menu items are now lexically sorted (default items and favorites order will be preserved)
|
||||
* Wiki syntax : Added ""marked text"" support (HTML5 only)
|
||||
* Session TTL are now adjustable (set DC_SESSION_TTL in inc/config.php)
|
||||
* Add behaviors for posts/pages/comments/users lists' columns → let 3rd party plugin playing with them
|
||||
* Blog and user lists are now lexically sorted
|
||||
* Some new filters have been added for post lists
|
||||
* Add a search engine in media manager (looking in filename, title and description metadata)
|
||||
* Add recent folders direct access mechanism for the media manager (setting in user prefs)
|
||||
* Add a another display mode (list) to the media manager
|
||||
* Details about currently selected thumbnail in media manager are now displayed
|
||||
* Shortcut access to the upload file form is now displayed on top on media page
|
||||
* Default insertion size (width and height) may now be defined for video media
|
||||
* Flash player fallback insertion is now optional for audio and video media
|
||||
* Modules may have dependencies on Dotclear core version too (using 'core' as module name)
|
||||
* Avoid mixed content (http vs https) for post/page preview: will open preview in another window if necessary
|
||||
* Finnish translation has been added
|
||||
* Content-length header is not more sent in HTTP response (should fix very long delays on some servers)
|
||||
* Template engine : add tpl:EntryAuthorEmailMD5 and tpl:EntryCategoryDescription tags
|
||||
* A new pref/setting array type is now available (JSON encoded in db)
|
||||
* Cope with sort of "un-attached" media → allows new features as "featured media" plugin
|
||||
* CKEditor library updated from 4.5.1 to 4.5.8
|
||||
* Update jQuery from 1.11.3 to 2.2.0, jQuery-migrate from 1.2.1 to 1.3.0, jQuery-ui-custom from 1.11.2 to 1.11.4
|
||||
* Provide jQuery 2.2.0 for public use (themes/plugins) - 1.4.2 (default) and 1.11.3 still provided
|
||||
* Some locales added or updated
|
||||
* PHP 7 compliance, PHP 5.3 min
|
||||
* Fix : Cope with "unknown" scheme in url (ie nor http: neither https: is defined in origin url)
|
||||
* Fix : Let select another theme even if theme folder is read-only
|
||||
* Fix : XML-RPC media uploaded are not more twice Base64 decoded
|
||||
* And plenty of other 🐛 🔫, various 🌼 adjustments, and also lot of 🍻 drunk
|
||||
|
||||
Dotclear 2.8.2 - 2015-10-25
|
||||
===========================================================
|
||||
* Security fix : Fixed potential XSS on comments management page
|
||||
* Security fix : Enforce media exclusion control
|
||||
* Php 5.5 leaves NULL chars in unpack ==> add trim, fixed
|
||||
* Media title (in standard mode) is now taken into account on upload
|
||||
* Some 🐛 🔫
|
||||
|
||||
Dotclear 2.8.1 - 2015-09-23
|
||||
===========================================================
|
||||
* Fix admin pager parameters escaping - thanks Keiko Yashiki from JPCERT/CC for reporting this XSS
|
||||
* Error on changing post author in entries' lists: fixed
|
||||
* Cope with unknown URL scheme in X-Frame-Options
|
||||
* One ot two of 🍻 drunk
|
||||
|
||||
Dotclear 2.8 - 2015-08-13
|
||||
===========================================================
|
||||
* New module dependencies system (plugins)
|
||||
* Theme editor: Cope with css theme sub-folder
|
||||
* extension/heritage system applied to mustek templateset
|
||||
* installation wizard now allows SQLite engine
|
||||
* Legacy editor toolbar may now be displayed below textarea
|
||||
* Breadcrumb plugin added to the distribution, included in mustek/currywurst templatesets
|
||||
* Allow a fifth parameter (optional) for image to insert a legend using figure/figcaption tags (wiki)
|
||||
* XHTML validator removed from legacy editor
|
||||
* Update jQuery from 1.11.2 to 1.11.3
|
||||
* Add a blog parameter to disable internal search
|
||||
* Add some sort orders and filters criteria for posts and comments
|
||||
* Update CKEditor from 4.4.8 to 4.5.2
|
||||
* Add IP and antispam filter columns when displaying spams
|
||||
* Add actions to directly blacklist IP from comments list
|
||||
* Lexical sort order for tags and widgets
|
||||
* Use HTML5 audio tag for MP3 attachments
|
||||
* Bye the 🐈, welcome the 🐸
|
||||
* Lot of 🐛 🔫
|
||||
* Various 🌼 adjustments
|
||||
* Full of 🍻 drunk
|
||||
|
||||
Dotclear 2.7.4 - 2015-02-13
|
||||
===========================================================
|
||||
* Berlin theme: resources usage has been optimized
|
||||
* currywurst templateset: head-linkrel block name fixed
|
||||
* Current editor syntax: now displayed near edited field (post/page/quick entry)
|
||||
* Some admin URLs were malformed: fixed
|
||||
* Post/page preview: anti-clickjacking system fixed
|
||||
* The cat is valid now
|
||||
|
||||
Dotclear 2.7.3 - 2015-01-13
|
||||
===========================================================
|
||||
* Restore advanced edition of category description (as in 2.6)
|
||||
* Various bug fixes
|
||||
* Some cosmetic adjustments
|
||||
|
||||
Dotclear 2.7.2 - 2014-12-25
|
||||
===========================================================
|
||||
* Dotclear wiki could not be used by standard user: fixed
|
||||
|
||||
Dotclear 2.7.1 - 2014-12-25
|
||||
===========================================================
|
||||
* Various bug fixes
|
||||
* Some cosmetic adjustments
|
||||
|
||||
Dotclear 2.7 - 2014-12-13
|
||||
===========================================================
|
||||
* Security : protection against clickjacking may be activated (see blog parameters)
|
||||
* Switch to HTML5 : backend, templatesets and themes
|
||||
* ARIA roles in da place (a11y)
|
||||
* Multiple templatesets : mustek (legacy) and currywurst
|
||||
* Themes may use extension/heritage template mechanisms
|
||||
* New theme (Berlin) based on currywurst templateset
|
||||
* New WYSIWYG editor (CKEditor)
|
||||
* Dotclear Wiki now produces HTML5 compatible markup
|
||||
* Video and audio HTML5 tags are now used (with fallback to flash if possible)
|
||||
* Copying default theme to user-defined theme folder is not more necessary
|
||||
* Preview of comment may be optional (see blog parameters)
|
||||
* Widgets may be put offline without deleting them
|
||||
* jQuery version may be choosen between 1.4.2 (default) and 1.11.1 (see blog parameters)
|
||||
* Number of posts listed on home page may be different than other pages (see blog parameters)
|
||||
* Hidden folders are now hidden in media manager (set DC_SHOW_HIDDEN_DIRS to true in config.php to display them)
|
||||
* User-defined template files may be reset (deleted) in theme editor
|
||||
* Drag'n'drop now enabled on touch screens
|
||||
* Alternative syntax may be set for comments by third-party plugins
|
||||
* A lot of bug fixes
|
||||
* Much more cosmetic adjustements and enhancements
|
||||
|
||||
Dotclear 2.6.4 - 2014-08-18
|
||||
===========================================================
|
||||
* Security fix: Sanitize search request. Thanks to Takayuki Uchiyama
|
||||
* Security fix: Strenghened xmlrpc (see http://www.breaksec.com/?p=6362)
|
||||
|
||||
Dotclear 2.6.3 - 2014-05-16
|
||||
===========================================================
|
||||
* Security fix: Strengthened xmlrpc auth. Thanks to Egidio Romano
|
||||
* Security fix: Strengthened categories ordering. Thanks to Egidio Romano
|
||||
|
||||
Dotclear 2.6.2 - 2014-01-20
|
||||
===========================================================
|
||||
* Security fix: Fixed potential code injection on password protected post/page. Thanks to Charlie Briggs
|
||||
* Bugfix: cope with numeric module (plugin/theme) id
|
||||
* Bugfix: Bad SQL syntax when using SQLite
|
||||
* Bugfix: BlogParentThemeURL template value is back
|
||||
* Various bug fixes
|
||||
|
||||
Dotclear 2.6.1 - 2013-11-22
|
||||
===========================================================
|
||||
* Bugfix: trackbacks/pingbacks post URL
|
||||
* Bugfix: short/full list of tags (post edition)
|
||||
* Bugfix: Toolbar not drawn on new comment form (administration)
|
||||
* Various bug fixes
|
||||
* Some cosmetic adjustments
|
||||
|
||||
Dotclear 2.6 - 2013-11-13
|
||||
===========================================================
|
||||
* Various bug fixes
|
||||
* Various cosmetic adjustments
|
||||
|
||||
Dotclear 2.6-RC - 2013-10-18
|
||||
===========================================================
|
||||
* PHP 5.2 required
|
||||
* jQuery upgraded to 1.10.2 (including jQuery migrate plugin 1.2.1)
|
||||
* mySQLi support (now proposed by default rather than mySQL)
|
||||
* Administration revamped, relooked, redesigned, new icons, new ergonomic's behaviours
|
||||
* Administration is now responsive (easier to cope with it on small devices)
|
||||
* Administration menu re-organized
|
||||
* a11y (accessibility) everywhere, with and whithout Js
|
||||
* Success, notice and warning messages have been harmonized
|
||||
* daInstaller has been dispatched in core (in plugins and blog themes management)
|
||||
* Global help is now available, contextual help is available on every page
|
||||
* Media manager enhanced
|
||||
* Maintenance plugin revamped and enhanced (now includes export features)
|
||||
* Categories management enhanced
|
||||
* Plugins and themes management revamped
|
||||
* New “Plumetis” variation for Blowup theme
|
||||
* Jasmine is now used for unit testing of js components
|
||||
* A lot of bug fixes
|
||||
* A lot of cosmetics adjustments
|
||||
* A lot of enhancements
|
||||
|
||||
Dotclear 2.5.3 - 2013-09-13
|
||||
===========================================================
|
||||
* Bugfix: l10n Clearbricks library
|
||||
* Bugfix: post's comments and trackbacks counters
|
||||
* Check public and cache directories (existence and permissions)
|
||||
* Avoid Categorie's identical URL as far as possible
|
||||
* Cope with alpha layers in PNG images for thumbnails generation
|
||||
* Add password strength indicators
|
||||
* Fix permission form (checkboxes management)
|
||||
* Better management of antispam filters
|
||||
* Minor enhancements
|
||||
* Various bug fixes
|
||||
* Various cosmetic adjustments
|
||||
|
||||
Dotclear 2.5.2 - 2013-08-14
|
||||
===========================================================
|
||||
* Security fix: Fixed potential XSS
|
||||
* Bugfix: l10n Clearbricks library
|
||||
* <tpl:LoopPosition> now works <tpl:Attachments>
|
||||
* Dotclear update check may now be forced (ignoring cache)
|
||||
* Enforce integration of daInstaller plugin
|
||||
* Tags link button is now available on page editor
|
||||
* Default cache age is now 1 week instead of 2 hours
|
||||
* Quick entry dashboard module is not activated by default on new installation
|
||||
* New template {{tpl:BlogParentThemeURL}} (return URL of parent theme of blog's theme if any, URL of blog's theme otherwise)
|
||||
* Fix post comments number on comments deletion
|
||||
* Fix order of backup files
|
||||
* Minor enhancements
|
||||
* Various bug fixes
|
||||
* Various cosmetic adjustments
|
||||
|
||||
Dotclear 2.5.1 - 2013-07-20
|
||||
===========================================================
|
||||
* Security fix: Replacement of swfupload.swf by a jQuery plugin
|
||||
* Security enhancement: Strenghened lists display
|
||||
* Thumbnails quality improved
|
||||
* Minor enhancements
|
||||
* Various bug fixes
|
||||
* Various cosmetic adjustments
|
||||
|
||||
Dotclear 2.5.0 - 2013-03-12
|
||||
===========================================================
|
||||
* Security fix: XSS vulnerabilities in swfupload.swf (media enhanced uploader)
|
||||
* Ductile theme may now use webfont (from Google, Adobe and similar providers)
|
||||
* daInstaller plugin is now included in the official distribution
|
||||
* The media enhanced uploader may now be temporarily enabled or disabled
|
||||
* Add mass expand on posts and comments lists
|
||||
* Allow wildcard for IP address on comments filters
|
||||
* Add ability to delete non empty category (and move its content to another category)
|
||||
* Every types of entries may be used to inserted an entry link in current edited post
|
||||
* Add (none) option to image insertion title pattern
|
||||
* Smileys are not more converted in image in pre,code,kbd,script and math contents
|
||||
* Notes' title can be now enclosed in h4 (default), h3 or p HTML tag
|
||||
* Now display translated name and desc of plugins
|
||||
* Add publication date validation on post and page editing forms
|
||||
* Add description to widgets
|
||||
* Add syntax color option to theme editor plugin
|
||||
* Add delete button on media item page
|
||||
* Add/complement display modes (all pages, home page only, except on home page) for all widgets
|
||||
* {{tpl:Widgets}} without type attribute set displays now all widgets (from nav, extra and custom)
|
||||
* Add {{tpl:else}}, {{tpl:TagCount}}, <tpl:TagIf>, {{tpl:CategoryEntriesCount}} template tags
|
||||
* Add cat_only, no_tag and content_only attributes to {{tpl:EntryFirstImage}} tag
|
||||
* Add capitalize attribute to template filters' list
|
||||
* Enhance links lookup anti spam filter
|
||||
* Add hidden optional attribute for pages
|
||||
* Adaptative compression rate for thumbnails generation
|
||||
* Add timestamp on admin information messages
|
||||
* Update to jQuery 1.8.3 and jQuery-UI 1.9.2 (custom)
|
||||
* Add default favicon.ico
|
||||
* Add default attributes settings for image,mp3,flv insertion
|
||||
* Various bug fixes
|
||||
* Various cosmetic updates and contrast adjustments
|
||||
|
||||
Dotclear 2.4.4 - 2012-08-13
|
||||
===========================================================
|
||||
* Bugfix: Programmed entries works again.
|
||||
* Compatibility fix: widgets are now fully php >=5.3 compliant
|
||||
* Security fix: potential CSRF in user management
|
||||
* has_tag now part of dotclear core, moved from tag plugin.
|
||||
* empty title fixed on rss reader widget
|
||||
|
||||
Dotclear 2.4.3 - 2012-05-18
|
||||
===========================================================
|
||||
* Admin: My favorites menu can be hidden
|
||||
* Admin: Fix wordpress importer
|
||||
* Admin: about:config and user:pref tables are now more readable
|
||||
* Ductile theme: Blog logo can be changed
|
||||
* New lithuanian language (thanks to Paulius Černakauskas)
|
||||
* Various bug fixes
|
||||
|
||||
Dotclear 2.4.2 - 2012-02-11
|
||||
===========================================================
|
||||
* Security fix release
|
||||
* 4 XSS vulnerabilities fixed, discovered by High-Tech Bridge
|
||||
|
||||
Dotclear 2.4.1.2 - 2011-12-24
|
||||
===========================================================
|
||||
* Happy Christmas!
|
||||
* Security: fixed one SQL injection vulnerability in Clearbricks, thanks to Adjaya
|
||||
* New behaviour: publicGetURLFor
|
||||
* New behaviour: publicRegisterURL
|
||||
* New behaviour: templatePrepareParams
|
||||
* Changed the way to get artefacts URLs, through $core->url->getURLFor calls, instead of $core->url->getBase()
|
||||
* new/updated parameter sql_only in $core->blog->getPosts and $core->blog->getComments
|
||||
|
||||
Dotclear 2.4.0 - 2011-11-13
|
||||
===========================================================
|
||||
* Admin: new iconset from Thomas Daveluy
|
||||
* Admin: Accessibility enhancements
|
||||
* Added a custom widget sidebar
|
||||
* Added a new theme (Ductile)
|
||||
* Added a new plugin (simpleMenu)
|
||||
* handling of postgres non default schemas (db_prefix = 'schema.prefix')
|
||||
* New iconset mechanism
|
||||
* New behaviour: coreBlogBeforeGetPosts
|
||||
* Security fix: Spam comments feed now checks for blog permission. Thanks to Romuald Brunet.
|
||||
* Various bug fixes
|
||||
|
||||
Dotclear 2.3.1 - 2011-06-14
|
||||
===========================================================
|
||||
* Updated makefile for cleaner distrib.
|
||||
* Better localization handling for prefs and shortcuts.
|
||||
* Misc JS & CSS cleaning.
|
||||
* Import/Export preferences-related bugfix.
|
||||
* Administrative mail address is now configurable.
|
||||
* Security: one minor fix and changes for two potential problems. Thanks to Jeremie Boutoille
|
||||
|
||||
Dotclear 2.3.0 - 2011-05-16
|
||||
===========================================================
|
||||
* Admin: Major backend redesign
|
||||
* Admin: Customizable Dashboard
|
||||
* Admin: New Favourites admin submenu
|
||||
* Admin: New user preferences backend
|
||||
* Admin: Accessibility enhancements
|
||||
* Admin: Inline help extended
|
||||
* Templates: Default theme templates moved to inc/public/default-templates
|
||||
* Clearbricks: External libraries relocated to inc/libs
|
||||
* Clearbricks: fixed utf-8 and mysql strict mode problems
|
||||
* Added a safe mode connection, disabling all plugins
|
||||
* Mysqli support (config.php may need to be updated manually)
|
||||
* Fixed dcLog bug with pgsql
|
||||
* Fixed comment/trackbacks counters reset.
|
||||
* Several other bug fixes
|
||||
|
||||
|
||||
Dotclear 2.2.3 - 2011-04-01
|
||||
===========================================================
|
||||
* Security fix in media manager. Thx to Raphaël
|
||||
* Bugfix : 2.2.2 was preventing manual thumbnail regeneration.
|
||||
* Database handling bugfixes
|
||||
|
||||
Dotclear 2.2.2 - 2011-01-17
|
||||
===========================================================
|
||||
* Bugfix: 2.2.1 was blocking new installations
|
||||
* Autoupdate procedure should now be "bad ftp client configuration"-proof.
|
||||
* Several other small bugfixes
|
||||
|
||||
Dotclear 2.2.1 - 2011-01-15
|
||||
===========================================================
|
||||
* ExternalMedia is not part of the core distribution anymore
|
||||
* New attribute to tpl:SysIf: blog_id
|
||||
* New behaviour: adminMediaItemForm
|
||||
* Several bugfixes
|
||||
* Several code optimizations
|
||||
* Several typos corrected
|
||||
* Security fix in Clearbricks. Thx to François Pierre-Doray for pointing it out.
|
||||
|
||||
Dotclear 2.2 - 2010-07-01
|
||||
===========================================================
|
||||
* New installation wizard.
|
||||
* Several new behaviours:
|
||||
- adminCommentHeaders
|
||||
- adminCommentsActionsCombo
|
||||
- adminCommentsActions
|
||||
- adminCommentsActionsContent
|
||||
- adminBeforeCommentDelete
|
||||
- adminPostsActionsHeaders
|
||||
- adminUsersActionsCombo
|
||||
- coreBeforeCategoryCreate & coreAfterCategoryCreate
|
||||
- coreBeforeCategoryUpdate & coreAfterCategoryUpdate
|
||||
- coreBeforeLogCreate & coreAfterLogCreate
|
||||
- coreBeforePostCreate & coreAfterPostCreate
|
||||
- coreBeforePostUpdate & coreAfterPostUpdate
|
||||
- coreMediaConstruct
|
||||
- templateCustomSortByAlias
|
||||
- urlHandlerGetArgsDocument
|
||||
* New methods for several core classes.
|
||||
* Metadata integration to the core.
|
||||
* Error handlers can now be extended.
|
||||
* Templates: blocks can now be recursive.
|
||||
* Templates: Entries & Comments tags can now be sorted.
|
||||
* Templates: The template subsystem is quicker, linier, and ready to be extended.
|
||||
* Complete reworking of the settings system
|
||||
* Correct handling of postgresql non default schemas.
|
||||
* Admin: Autocompletion and further enhancing to tags handling.
|
||||
* Admin: Accessibility & ergonomic tweaks.
|
||||
* Admin: Administrator tag in users list.
|
||||
* Comment cookies are now specific to the blog rather than to the domain.
|
||||
* Password changes can now be mandatory.
|
||||
* jQuery updated to 1.4.2.
|
||||
* And way too many bugfixes and typos squashes to be listed.
|
||||
|
||||
|
||||
Dotclear 2.1.7 - 2010-05-25
|
||||
===========================================================
|
||||
* Auto-update procedure fix
|
||||
|
||||
Dotclear 2.1.6 - 2009-10-01
|
||||
===========================================================
|
||||
* Install procedure fixes
|
||||
* Admin: Page managers can now create pages
|
||||
* Admin: several typos corrected.
|
||||
* Admin: Widgets now work in IE8.
|
||||
* Admin: Password protected posts can now be previewed.
|
||||
* Templates: tpl:Meta* are now tpl:Tags*.
|
||||
* Templates: <tpl:Entries lastn="0"> now display all posts.
|
||||
* new behavior: adminPageHTMLHead
|
||||
* DB schema: new blog_id field in log table
|
||||
* Media manager: Pubic folder can now be set on a different host.
|
||||
* WordPress import fixes
|
||||
* Dailymotion insertion fix
|
||||
* Upgrade procedure: CRLF removed in files that were bugging the upgrade.
|
||||
* JQuery updated to 1.3
|
||||
* IE7-js update
|
||||
* security: Full Path Disclosure protection. Thx to Karim Ayad for pointing it out.
|
||||
* and way too many bugfixes to be listed.
|
||||
|
||||
Dotclear 2.1.5 - 2009-02-05
|
||||
===========================================================
|
||||
* Security release
|
||||
* Youtube insertion update
|
||||
|
||||
Dotclear 2.1.4 - 2008-12-21
|
||||
===========================================================
|
||||
* Security flaw fix
|
||||
* WordPress import refining
|
||||
* XML-RPC improvements
|
||||
|
||||
Dotclear 2.1.3 - 2008-11-19
|
||||
===========================================================
|
||||
* Admin: New upgrade procedure
|
||||
* Admin: Fixed video insertion bug
|
||||
* Template: New attributes
|
||||
* url on EntryIf
|
||||
* only_category on Blogroll
|
||||
* no_context on Pagination
|
||||
* Template: New tag
|
||||
* BlogID
|
||||
* Admin: escaped blog_id on authentication page
|
||||
|
||||
Dotclear 2.1.1 - 2008-11-07
|
||||
===========================================================
|
||||
* Admin: Automatic Update bug fixes
|
||||
* Admin: Disable Automatic Update if no digests file
|
||||
* Admin: Javascript fixes in authentication page
|
||||
* Admin: Fixed errors with categories select boxes
|
||||
* Template: Added level attribute in tpl:Categories
|
||||
* Media: Added H.264/MPEG-4 AVC for mp4 files
|
||||
|
||||
Dotclear 2.1 - 2008-11-01
|
||||
===========================================================
|
||||
* Subcategories
|
||||
* Admin: Automatic Update
|
||||
* Admin: Flash 10 support for uploader
|
||||
* Admin: mailto link in comment details
|
||||
* Admin: Embedded video size selection
|
||||
* Admin: Restrict session cookie path to admin
|
||||
* Media: H.264/MPEG-4 AVC (HD) support with m4v files
|
||||
* Inherited themes
|
||||
* WordPress XML-RPC methods support
|
||||
* True unicode URLs
|
||||
* Plugin: Widgets as template tags
|
||||
* Plugin: Filters in entries widgets and Blogroll
|
||||
* Plugin: Added vimeo.com in external media
|
||||
* Template: New tags
|
||||
* LoopPosition
|
||||
* CommentAuthorDomain
|
||||
* CommentAuthorMD5
|
||||
* EntryFirstImage
|
||||
* EntryCategoryShortURL
|
||||
* CategoryIf
|
||||
* CategoryFirstChildren
|
||||
* CategoryParents
|
||||
* EntryCategoriesBreadcrum
|
||||
* MediaURL
|
||||
|
||||
Dotclear 2.0.2 - 2008-09-05
|
||||
===========================================================
|
||||
* New installation procedure
|
||||
* Plugin: WordPress import fixes
|
||||
* Plugin: Plain text export as downloadable files
|
||||
* Plugin: Message about URLs in Dotclear 1.2 import
|
||||
* Public: Display a message if search returns no result
|
||||
* Admin: Fixed some CSS bugs
|
||||
* Admin: Batch select/unselect entries
|
||||
* Admin: In a media item, find entries containing it
|
||||
|
||||
Dotclear 2.0.1 - 2008-08-16
|
||||
===========================================================
|
||||
* Plugin: Fixed a bug with Dotclear 1.2 URLs import.
|
||||
* Plugin: Fixed a l10n bug in Pages
|
||||
* Admin: Enhanced plugins resources loading and cache
|
||||
|
||||
Dotclear 2.0 - 2008-08-01
|
||||
===========================================================
|
||||
* Public: Atom becomes the default feed format. RSS 2 is always available.
|
||||
* Admin: design enhancements and new Dotclear logo
|
||||
* Admin: entries preview in blog context
|
||||
* L10N: New language manager with zip files support
|
||||
* Plugin: Import/Export plugin version 2.0 with import from Dotclear 1.2 and WordPress
|
||||
* Plugin: Pages enhancements (preview, sorting)
|
||||
* Plugin: support for jamendo and deezer in External Media
|
||||
* JSMin on JavaScript files instead of JS packing
|
||||
* SQLite 3 only support (PDO based)
|
||||
* Many bug fixes and major performances improvements
|
||||
|
||||
Dotclear 2.0 RC2 - 2008-06-21
|
||||
===========================================================
|
||||
* FairTrackback spam filter
|
||||
* Language pack infrastructure
|
||||
* Bug fix on comment search with author "0"
|
||||
* Javascript fixes
|
||||
* dcAuth::sessionExists and dcAuth::checkSession new methods
|
||||
* Right management in dcAuth::sudo
|
||||
* Media File sorting options in media manager
|
||||
* CandyUpload, new uploader tool based on SWFUpload
|
||||
* New search engine robots options
|
||||
* New image options
|
||||
* L10N: Japanese and Portugues (Brazil) language packs
|
||||
* Many bug fixes and enhancements
|
||||
|
||||
Dotclear 2.0 RC1 - 2008-05-01
|
||||
===========================================================
|
||||
* New: Pages plugin
|
||||
* New: Theme editor plugin
|
||||
* Entries: Text and WYSIWYG enhancements
|
||||
* Entries: Markup validator
|
||||
* Entries: Insertion of links to other entries from toolbar
|
||||
* Entries: External media insertion (dailymotion, youtube, google video)
|
||||
* Tags: Same list for new and existing entries
|
||||
* Tags: Tags can be removed on all associated entries
|
||||
* Tags: Tags can be removed on a post selection
|
||||
* Admin: Ask password for user management tasks, theme upload and plugin upload
|
||||
* Admin: New contextual help viewer
|
||||
* Media manager: Recreate thumbnails option
|
||||
* Media manager: Custom medium thumbnail size (per blog)
|
||||
* Media manager: Zip files extract support
|
||||
* Media manager: Zip file download of directory
|
||||
* Media manager: File exclusion pattern option
|
||||
* Themes and plugins: Zip as new package format
|
||||
* Themes and plugins: Upload
|
||||
* Themes and plugins: Upgrade within administration interface
|
||||
* Themes and plugins: Deletion
|
||||
* Public: New default theme: Blowup (fully customizable)
|
||||
* Public: Changed the way commenter cookie is handled
|
||||
* Themes: Template files moved to tpl/ directory
|
||||
* L10N: Polish, Catalan and Spanish translations
|
||||
* Misc: jQuery upgraded to 1.2.3
|
||||
* Misc: Crushed png files
|
||||
* Fixed many bugs
|
||||
|
||||
Dotclear 2.0 beta 7 - 2007-07-12
|
||||
===========================================================
|
||||
* New way to display comments and trackbacks on entries in backend
|
||||
* Dashboard visual improvements
|
||||
* Default cache dir created by installation process
|
||||
* Option to limit posts and comments in feeds
|
||||
* Introduced UDBS for installation and upgrade
|
||||
* Changed handling of XML-RPC URLs
|
||||
* New option to force HTTPS redirect if wanted
|
||||
* Enforced cookies security (directory and ssl support)
|
||||
* Added Plugin auto-install and auto-upgrade support
|
||||
* Added trackbacks ttl and moderation preferences
|
||||
* Added an Internal search engine
|
||||
* FLV support in backend with Neolao player
|
||||
* Added nice messages if database is broken or Dotclear not installed
|
||||
* upgrade jQuery to 1.1.3
|
||||
* Fixed many bugs
|
||||
* Fixed security issues in backend
|
||||
|
||||
Dotclear 2.0 beta 6 - 2007-02-19
|
||||
===========================================================
|
||||
* New antispam plugin, with a set of filters (rbl, ipblacklist, spamwords, akismet)
|
||||
* New admin dashboard page
|
||||
* Fixed unwanted logout bug
|
||||
* Added settings to disable template caching and allow PHP code
|
||||
* Blog preferences panel bug fix
|
||||
* New XML-RPC Client and Server
|
||||
* Comment posting permissions bug fix
|
||||
|
||||
Dotclear 2.0 beta 5.4 - 2007-01-19
|
||||
===========================================================
|
||||
* Minor change on spam display in comments.php
|
||||
* Command line upgrade script and fix in load_plugin_file.php
|
||||
* Make akismet configurable only by superadmin with DC_AKISMET_SUPER
|
||||
* SQL optimisations
|
||||
* New comments view in post
|
||||
|
||||
Dotclear 2.0 beta 5.2 - 2007-01-11
|
||||
===========================================================
|
||||
* Fixed a bug with imageMeta::getMeta
|
||||
* Enhanced dynamic file uploader
|
||||
* Move clearbricks files to their own repository
|
||||
* Fixed a bug with auto_br in wikiSimpleComment
|
||||
* Support for language restriction in feeds
|
||||
* Default theme structure changes
|
||||
* Fixed a PHP 5.0 compatibility issue
|
||||
* Installation Wizard
|
||||
|
||||
Dotclear 2.0 beta 4 - 2006-12-26
|
||||
===========================================================
|
||||
* Performances enhancements.
|
||||
* Administration UI enhancements.
|
||||
* More user-friendly Widgets (version 1.5).
|
||||
* Switch to jQuery <http://jquery.com>.
|
||||
* Added jQuery in default theme.
|
||||
* Major changes in HTTP client and Feed Parser based on a
|
||||
generic socket handler.
|
||||
* PHP 5.2 compatibility.
|
||||
* Code documentation (all core and most of clearbricks).
|
||||
* Many bug fixes.
|
||||
|
||||
Dotclear 2.0 beta 3 - 2006-11-05
|
||||
===========================================================
|
||||
* Disallow special wrappers for fopen like functions.
|
||||
* XML/RPC improvements.
|
||||
* Read IPTC and EXIF metadata in uploaded pictures.
|
||||
* MySQL 4.1 support only.
|
||||
* Metadata import from Dotclear 1.2.x.
|
||||
* Akismet plugin.
|
||||
* Pings plugin.
|
||||
* Added a priority setting for plugins.
|
||||
* Many bug fixes.
|
||||
|
||||
Dotclear 2.0 beta 2 - 2006-08-09
|
||||
===========================================================
|
||||
* DC_PLUGIN_ROOT can handle more than one path.
|
||||
* OPML/XBEL import in blogroll plugin.
|
||||
* Fixed a security issue in html::absoluteURLs().
|
||||
* Fixed issues with timezone on scheduled entries.
|
||||
* Multiple categories selection in tpl:Entries.
|
||||
* Improved dbLayer.
|
||||
* Changed category feed URL.
|
||||
* Feeds for tags (entries and comments).
|
||||
* Added attachments count on backend and frontend.
|
||||
* New settings code design. Can now handle wide system settings.
|
||||
* Memory usage improvements with autoloader.
|
||||
* Some code cleanup.
|
||||
* Feed parser improvements.
|
||||
* Themes can be configured if needed.
|
||||
* XMP support on JPEG files.
|
||||
* Media manager improvements.
|
||||
* Spamplemousse now uses DNSBL (and the guy who left the bug was fired).
|
||||
* Javascript editor and toolbar improvements.
|
||||
* RDS support (XML/RPC API discovery).
|
||||
* Added a theme with user stylesheet.
|
||||
* Plugins manager
|
||||
9
dotclear._no/CONTRIBUTING.md
Normal file
@ -0,0 +1,9 @@
|
||||
# CONTRIBUTING
|
||||
|
||||
Dotclear is an open source project. If you'd like to contribute, you can send
|
||||
a pull request, or feel free to use any other way you'd prefer.
|
||||
|
||||
There are many way to contribute :
|
||||
|
||||
* Report bugs (https://git.dotclear.org/dev/dotclear and https://git.dotclear.org/dev/dotclear/issues/new)
|
||||
* Add documentation (https://dotclear.org/documentation/2.0 in English, https://fr.dotclear.org/documentation/2.0 in French)
|
||||
52
dotclear._no/CREDITS
Normal file
@ -0,0 +1,52 @@
|
||||
This is a credits file of people that have contributed to the Dotclear project.
|
||||
|
||||
Dotclear Team
|
||||
-------------
|
||||
|
||||
Thomas Bouron
|
||||
Luce Carević
|
||||
Anne Cavalier
|
||||
Noé Cendrier
|
||||
Benoit Clerc
|
||||
Grégory Corvisier
|
||||
Florent Cotton
|
||||
Jean-Christian Denis
|
||||
Gilles Aka Gvx
|
||||
Philippe Hénaff
|
||||
Bruno Hondelatte
|
||||
Franck Lafay
|
||||
Kévin Lepeltier
|
||||
Olivier Meunier
|
||||
Franck Paul
|
||||
Michel Pelletier
|
||||
Xavier Plantefève
|
||||
Nicolas Roudaire
|
||||
Jean-Michel Royer
|
||||
Anne Sophie Tranchet
|
||||
Alain Vagner
|
||||
|
||||
Dotclear Translators
|
||||
--------------------
|
||||
|
||||
Benjamin Bank
|
||||
Alain Béarez
|
||||
Claire Cambier
|
||||
Luis Correia
|
||||
Andreas Diller
|
||||
Alain Fagot
|
||||
Sabrina Favier
|
||||
Charles Hebert
|
||||
Guillaume Jonquiere
|
||||
Dennis S. L. Jørgensen
|
||||
Miguel A. Muñoz
|
||||
Sebestyén Muráncsik
|
||||
Nnidŷu
|
||||
Polo
|
||||
Aina Chabert Ramon
|
||||
Adnan Shameem
|
||||
Enrique Matias Sanchez
|
||||
Jan Skrasek
|
||||
Takafumi
|
||||
Regina Timbó
|
||||
|
||||
... and all contributors.
|
||||
339
dotclear._no/LICENSE
Normal file
@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
109
dotclear._no/README.md
Normal file
@ -0,0 +1,109 @@
|
||||
# README
|
||||
|
||||
## WHAT IS DOTCLEAR ?
|
||||
|
||||
Dotclear is an open-source web publishing software.
|
||||
Take control over your blog!
|
||||
|
||||
Dotclear project's purpose is to provide a user-friendly
|
||||
tool allowing anyone to publish on the web, regardless of
|
||||
their technical skills.
|
||||
|
||||
### Features:
|
||||
* Easy publication
|
||||
* Fully customizable theme
|
||||
* User-friendly administration
|
||||
* Flexible template system
|
||||
* Media management
|
||||
* Choose from several editing syntax (wiki, markdown, textile or directly in wysiwyg)
|
||||
* Flexible comment system
|
||||
* Built-in antispam
|
||||
* Localization
|
||||
* Presentation widgets
|
||||
* Themes and plugins
|
||||
* Pages
|
||||
* Tags and categories
|
||||
* Automated installation
|
||||
* Support for several database types
|
||||
* Multiblog
|
||||
* Multi-user with permissions
|
||||
* Standards compliant
|
||||
* Accessible
|
||||
* Importing / exporting
|
||||
* Naturally optimized for search engines
|
||||
* Syndication feeds
|
||||
* Complete trackback support
|
||||
* Full Unicode support
|
||||
* XML/RPC client support
|
||||
* Extensible
|
||||
* Performance and scalability
|
||||
* Twice free
|
||||
|
||||
|
||||
## REQUIREMENTS
|
||||
|
||||
In order to run Dotclear you need:
|
||||
|
||||
* A web server (Apache, Cherokee, Nginx, lighttpd, etc.)
|
||||
* PHP 5.6 with the following modules:
|
||||
* mbstring
|
||||
* iconv
|
||||
* simplexml
|
||||
* mysql, mysqli, postgresql or sqlite
|
||||
* A database server (MySQL or PostgreSQL) or SQLite.
|
||||
|
||||
|
||||
## INSTALLATION
|
||||
|
||||
### Automatic installation
|
||||
The easiest way to install the blog engine is automatic installation.
|
||||
Download the [one minute install file][1], upload it to your web space. Then open it in your favorite browser. You'll only have to follow the instructions on screen. See the [documentation][2] for more information.
|
||||
|
||||
### Standard installation.
|
||||
You need to download [Dotclear archive][3], extract it then upload your files to your web space using an FTP client.
|
||||
Then open your favorite browser and go to http://your.host.name/dotclear/admin/install/. A message alerts you that you haven't got a configuration file and offers to run the wizard. Click this link.
|
||||
|
||||
|
||||
## DOCUMENTATION
|
||||
Still unsure if you want to move? A "[guided tour][4]" is what you need.
|
||||
|
||||
Dotclear is fully documented:
|
||||
|
||||
* If you have moved in already, the [User Manual][5] is there for you.
|
||||
* The managers will turn to the [Administration Guide][6].
|
||||
* Decorators and craftsmen will surely enjoy reading the [Developer and designer resources][7].
|
||||
|
||||
Dotclear documentation uses a wiki. Feel free to contribute.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Copyright Olivier Meunier & Association Dotclear
|
||||
|
||||
GPL-2.0-only (https://www.gnu.org/licenses/gpl-2.0.html)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
|
||||
CONTRIBUTING
|
||||
------------
|
||||
Dotclear is an open source project. If you'd like to contribute, please read the [CONTRIBUTING file](CONTRIBUTING.md).
|
||||
You can submit a pull request, or feel free to use any other way you'd prefer.
|
||||
|
||||
Repositories:
|
||||
-------------
|
||||
https://git.dotclear.org/dotclear/ (official)
|
||||
https://github.com/dotclear/dotclear (Github)
|
||||
|
||||
|
||||
[1]: https://download.dotclear.org/loader/dotclear-loader.php
|
||||
[2]: https://dotclear.org/documentation/2.0/admin/install
|
||||
[3]: https://dotclear.org/download
|
||||
[4]: https://dotclear.org/documentation/2.0/overview/tour
|
||||
[5]: https://dotclear.org/documentation/2.0/usage
|
||||
[6]: https://dotclear.org/documentation/2.0/admin
|
||||
[7]: https://dotclear.org/documentation/2.0/resources
|
||||
601
dotclear._no/admin/_charte.php
Normal file
@ -0,0 +1,601 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*/
|
||||
|
||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
||||
|
||||
dcPage::check('usage,contentadmin');
|
||||
$core->auth->user_prefs->addWorkspace('interface');
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="ROBOTS" content="NOARCHIVE,NOINDEX,NOFOLLOW" />
|
||||
<meta name="GOOGLEBOT" content="NOSNIPPET" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Bibliothèque de styles - Dotclear - 2.7</title>
|
||||
<link rel="icon" type="image/png" href="images/favicon96-login.png" />
|
||||
<?php
|
||||
$js = [];
|
||||
if ($core->auth->user_prefs->interface->darkmode) {
|
||||
echo dcPage::cssLoad('style/default-dark.css');
|
||||
} else {
|
||||
echo dcPage::cssLoad('style/default.css');
|
||||
}
|
||||
if ($core->auth->user_prefs->interface->htmlfontsize) {
|
||||
$js['htmlFontSize'] = $core->auth->user_prefs->interface->htmlfontsize;
|
||||
}
|
||||
// Set some JSON data
|
||||
echo dcUtils::jsJson('dotclear_init', $js);
|
||||
?>
|
||||
<script src="js/jquery/jquery.js"></script>
|
||||
<script src="js/jquery/jquery-ui.custom.js"></script>
|
||||
<script src="js/jquery/jquery.ui.touch-punch.js"></script>
|
||||
<script src="js/jquery/jquery.pageTabs.js"></script>
|
||||
<script src="js/jquery/jquery.biscuit.js"></script>
|
||||
<script src="js/prepend.js"></script>
|
||||
<script src="js/common.js"></script>
|
||||
<script src="js/prelude.js"></script>
|
||||
<script src="js/_charte.js"></script>
|
||||
</head>
|
||||
|
||||
<body id="dotclear-admin" class="no-js guideline<?php $core->auth->user_prefs->interface->dynfontsize ? ' responsive-font' : '';?>">
|
||||
<ul id="prelude">
|
||||
<li><a href="#content">Aller au contenu</a></li>
|
||||
<li><a href="#main-menu">Aller au menu</a></li>
|
||||
<li><a href="#qx">Aller à la recherche</a></li>
|
||||
</ul>
|
||||
<div id="header">
|
||||
<h1><a href="./index.php"><span class="hidden">Dotclear</span></a></h1>
|
||||
<div id="top-info-blog">
|
||||
<p>Bibliothèque de styles - Dotclear - 2.6+</p>
|
||||
</div>
|
||||
<ul id="top-info-user"><li>Octobre 2013</li></ul>
|
||||
</div><!-- /header -->
|
||||
|
||||
<div id="wrapper" class="clearfix">
|
||||
<div class="hidden-if-no-js collapser-box"><button type="button" id="collapser" class="void-btn">
|
||||
<img class="collapse-mm visually-hidden" src="images/collapser-hide.png" alt="Cacher le menu" />
|
||||
<img class="expand-mm visually-hidden" src="images/collapser-show.png" alt="Montrer le menu" />
|
||||
</button></div>
|
||||
<div id="main">
|
||||
<div id="content" class="clearfix">
|
||||
<h2>Typographie</h2>
|
||||
<h3 id="texte">Textes</h3>
|
||||
<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
|
||||
en pixels pour rester compatible avec Internet Explorer. L'interlignage courant est à 1.5.</p>
|
||||
<p>La liste suivante est de class <code>"nice"</code>. Elle est semblable aux listes ordinaires mais avec des puces carrées.</p>
|
||||
<ul class="nice">
|
||||
<li>Les textes courants sont en Arial, Helvetica ou sans-serif. </li>
|
||||
<li>Le code adopte la fonte Andale Mono, Courier New ou monospace.</li>
|
||||
<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>
|
||||
</ul>
|
||||
|
||||
<h3 id="titres">Titre h3</h3>
|
||||
<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>
|
||||
<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>
|
||||
<h4>Titre de niveau h4</h4>
|
||||
<p>On peut obtenir visuellement l'aspect d'un titre h4 en donnant à l'élément la class <code>"as_h4"</code>.</p>
|
||||
<h5>Titre de niveau h5</h5>
|
||||
<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
|
||||
h5 pour certains éléments du sidebar du billet, mais un style particulier leur est alors appliqué pour ressembler aux autres
|
||||
items de ce sidebar.</p>
|
||||
<div class="fieldset">
|
||||
<h4>Titres des encadrés</h4>
|
||||
<p>Les titres de boîte encadrées (div de class <code>"fieldset"</code>, comme ici) se présentent comme ci-dessus.</p>
|
||||
<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>
|
||||
</div>
|
||||
<h4 class="smart-title">Autre variante</h4>
|
||||
<p>On dispose également d'une class <code>"smart-title"</code> pour obtenir une présentation comme celle du titre de ce paragraphe.</p>
|
||||
|
||||
<h2>Layouts</h2>
|
||||
|
||||
<h3 id="onglets">Onglets</h3>
|
||||
<p>Les descriptions des constructions en multi-colonnes ci-dessous présentent un exemple de répartition en onglets.</p>
|
||||
<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>
|
||||
|
||||
<h3 id="multi-colonnage">Multi-colonnage</h3>
|
||||
<div id="one-box" class="multi-part" title="One-box">
|
||||
<h4>Boîtes distribuées horizontalement</h4>
|
||||
<div class="one-box">
|
||||
<div class="box">
|
||||
<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>
|
||||
</div>
|
||||
<div class="box">
|
||||
<p><span class="step">2</span> Voici une petite boîte.</p>
|
||||
</div>
|
||||
<div class="box">
|
||||
<p><span class="step">3</span> Une autre petite boîte.</p>
|
||||
</div>
|
||||
<div class="box">
|
||||
<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>
|
||||
</div>
|
||||
<div class="box">
|
||||
<p><span class="step">5</span> Si vous souhaitez un autre alignement des boîtes entre elles vous pouvez ajouter les class :</p>
|
||||
<ul class="nice clear">
|
||||
<li><code>"txt-left"</code>,</li>
|
||||
<li><code>"txt-right"</code></li>
|
||||
<li>ou <code>"txt-center"</code></li>
|
||||
</ul>
|
||||
<p>à la class <code>"one-box"</code>.</p>
|
||||
</div>
|
||||
<div class="box">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="two-boxes" class="multi-part" title="Two-boxes">
|
||||
<h4>Boîtes distribuées deux par deux</h4>
|
||||
<div>
|
||||
<div class="two-boxes odd">
|
||||
<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>
|
||||
</div><!--
|
||||
--><div class="two-boxes even">
|
||||
<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>
|
||||
</div><!--
|
||||
--><div class="two-boxes odd">
|
||||
<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="https://www.alsacreations.com/astuce/lire/1432-display-inline-block-espaces-indesirables.html">Alsacréations</a> (« Méthode 2 »).</p>
|
||||
</div><!--
|
||||
--><div class="two-boxes even">
|
||||
<div class="two-boxes odd">
|
||||
<p><span class="step">4</span> On peut bien sûr imbriquer des boîtes de class <code>"two-boxes"</code>
|
||||
au sein d'une boîte <code>"two-boxes" afin qu'elles…</code>…</p>
|
||||
</div><div class="two-boxes even">
|
||||
<p><span class="step">4 bis</span>… se distribuent horizontalement comme dans une boîte <code>"one-box"</code>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="three-boxes" class="multi-part" title="Three-boxes">
|
||||
<h4>Boîtes distribuées trois par trois</h4>
|
||||
<div>
|
||||
<div class="three-boxes">
|
||||
<div class="box">
|
||||
<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>
|
||||
</div>
|
||||
</div><!--
|
||||
--><div class="three-boxes">
|
||||
<div class="box">
|
||||
<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>
|
||||
</div>
|
||||
</div><!--
|
||||
--><div class="three-boxes">
|
||||
<div class="box">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="two-cols-50-50" class="multi-part" title="Two-cols (50/50)">
|
||||
<h4>Deux colonnes flottantes de largeurs égales</h4>
|
||||
<div class="two-cols clearfix">
|
||||
<div class="col">
|
||||
<p>La div englobante porte la class <code>"two-cols"</code>, chacune de ses div porte la class <code>"col"</code>.
|
||||
Sans autre précision les deux colonnes sont d'égale largeur.</p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="two-cols-70-30" class="multi-part" title="Two-cols (70/30)">
|
||||
<h4>Deux colonnes flottantes de largeurs inégales</h4>
|
||||
<div class="two-cols clearfix">
|
||||
<div class="col70">
|
||||
<p><span class="step">col70</span> La div englobante porte la class <code>"two-cols"</code>.
|
||||
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>
|
||||
</div>
|
||||
<div class="col30">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="three-cols" class="multi-part" title="Three-cols (deprecated)">
|
||||
<h4>Trois colonnes flottantes de largeurs égales</h4>
|
||||
<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>
|
||||
<div class="three-cols clearfix">
|
||||
<div class="col">
|
||||
<h5>Colonne 1</h5>
|
||||
<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>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h5>Colonne 2</h5>
|
||||
<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>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h5>Colonne 3</h5>
|
||||
<p>Voilà la troisième colonne.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<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>
|
||||
|
||||
<h2>Interactions</h2>
|
||||
|
||||
<h3 id="elements">Éléments de formulaire</h3>
|
||||
<form class="two-cols clearfix" action="#">
|
||||
<div class="col">
|
||||
<p><label for="ex1">Label simple + input text :</label><input id="ex1" type="text" /></p>
|
||||
<p class="form-note">p class="form-note".</p>
|
||||
<p><label for="ex4" class="classic">Label class="classic" + input text :</label> <input id="ex4" type="text" /></p>
|
||||
<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>
|
||||
<p><label for="ex11" class="bold">Label class="bold" :</label> <input id="ex11" type="text" /></p>
|
||||
<p class="form-note">La class="bold" est bien sûr à écrire en minuscules.</p>
|
||||
<p><label for="ex3">Input class="maximal" :</label> <input id="ex3" type="text" class="maximal" /></p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<p class="field"><label for="ex5">p.field label + input :</label><input id="ex5" type="text" /></p>
|
||||
<p class="field"><label for="ex6">p.field label + select :</label>
|
||||
<select id="ex6"><option value="opt2">Option 2</option><option selected="selected" value="opt2">Option 2</option></select>
|
||||
</p>
|
||||
<p><label class="classic" for="ex7"><input type="checkbox" checked="checked" id="ex7" value="1" name="ex7" />
|
||||
Checkbox (label.classic)</label></p>
|
||||
<p><label class="classic" for="ex8-1"><input type="radio" checked="checked" id="ex8-1" value="ex8-1" name="ex8-1" />
|
||||
Bouton radio 1 (label.classic)</label></p>
|
||||
<p><label class="classic" for="ex8-2"><input type="radio" id="ex8-2" value="ex8-2" name="ex8-2" />
|
||||
Bouton radio 2 (label.classic)</label></p>
|
||||
<p class="form-note">Les checkboxes et les boutons radio sont dans la balise <label>.</p>
|
||||
<p><label class="classic" for="ex9"><input type="checkbox"
|
||||
checked="checked" id="ex9" value="1" title="intitulé du champ" /></label> <label
|
||||
for="ex10" class="classic">checkbox.classic + label class="classic" :</label> <input id="ex10" type="text" /></p>
|
||||
</div>
|
||||
</form>
|
||||
<form action="#" class="clear">
|
||||
<fieldset>
|
||||
<legend>Légende de fieldset</legend>
|
||||
<p>Attention: Les fieldsets ne doivent être utilisés que pour isoler un groupe de champs au sein d'un formulaire.</p>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
<h3 id="boutons">Boutons</h3>
|
||||
<div class="clearfix">
|
||||
<p><a class="button add">a.button.add</a> Se place en haut à droite (dans un p.top-add)</p>
|
||||
<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>
|
||||
<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>
|
||||
<p><input type="submit" value="Type submit class disabled" class="disabled" /></p>
|
||||
</div>
|
||||
|
||||
<h3 id="messages">Messages</h3>
|
||||
<h4 class="smart-title">Messages système</h4>
|
||||
<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>
|
||||
<div class="message">
|
||||
<p>Message simple. Le plus souvent horodaté dcPage::message</p>
|
||||
</div>
|
||||
<div class="success">
|
||||
<p>Message de succès. Le plus souvent horodaté dcPage::success</p>
|
||||
</div>
|
||||
<div class="warning-msg">
|
||||
<p>Message warning. Non horodaté dcPage::warning</p>
|
||||
</div>
|
||||
<div class="error">
|
||||
<p>Message d'erreur. Non horodaté dcPage::error</p>
|
||||
</div>
|
||||
<p>La classe .static-msg peut être utilisée directement pour affichage en haut de page :</p>
|
||||
<div class="static-msg">
|
||||
<p>Comme le message simple mais sans effets de transition.</p>
|
||||
</div>
|
||||
<p>Un type de message réservé à Dotclear peut s'afficher en haut de la page :</p>
|
||||
<div class="dc-update">
|
||||
<h3>Dotclear 42 est disponible</h3>
|
||||
<p><a class="button submit" href="#">Mettre à jour maintenant</a>
|
||||
<a class="button" href="u#">Me le rappeler plus tard</a></p>
|
||||
<p class="updt-info"><a href="#">Informations sur cette version</a></p>
|
||||
</div>
|
||||
<h4 class="smart-title">Messages contextuels</h4>
|
||||
<p class="warn">Paragraphe de message d'alerte class warn ou warning.</p>
|
||||
<p class="info">Paragraphe de message de class info.</p>
|
||||
<p>Ces messages sont en display:inline-block. Le fond s'adapte à la longueur du message.</p>
|
||||
|
||||
<h2>Navigation</h2>
|
||||
|
||||
<h3 id="direct">Selecteur d'accès direct</h3>
|
||||
<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>
|
||||
<p class="anchor-nav">
|
||||
<label class="classic" for="lp_nav">Aller à : </label>
|
||||
<select id="lp_nav" name="lp_nav">
|
||||
<option value="#l_accessibility">accessibility</option>
|
||||
<option value="#l_dashboard">dashboard</option>
|
||||
<option value="#l_dmhostingmonitor">dmhostingmonitor</option>
|
||||
<option value="#l_dmpending">dmpending</option>
|
||||
<option value="#l_favorites">favorites</option>
|
||||
<option value="#l_filters">filters</option>
|
||||
<option value="#l_interface">interface</option>
|
||||
<option value="#l_lists">lists</option>
|
||||
<option value="#l_toggles">toggles</option>
|
||||
</select>
|
||||
<input type="submit" id="lp_submit" value="Ok" style="display: none;" />
|
||||
<input type="hidden" value="aboutConfig" name="p" />
|
||||
</p>
|
||||
<h3 id="prevnext">Navigation contextuelle</h3>
|
||||
<p><a title="Titre du lien" href="https://fr.dotclear.org/blog" class="onblog_link outgoing">Lien vers le blog <img alt="" src="images/outgoing-link.svg" /></a></p>
|
||||
<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>
|
||||
|
||||
<h3 id="pseudo-tabs">Pseudo-onglets </h3>
|
||||
<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>
|
||||
<p>Les pseudo-onglets sont à positionner immédiatement après le breadcrumb (ici un hr simule le trait sous le breadcrumb).</p>
|
||||
<p>Ces pseudo-onglets doivent être définis avec un <code><ul class="pseudo-tabs"></code> et des <code><li></code>.</p>
|
||||
<hr style="margin-bottom: .75em;" />
|
||||
<ul class="pseudo-tabs">
|
||||
<li><a href="#">Page 1</a></li>
|
||||
<li><a href="#">Autre faux onglet</a></li>
|
||||
<li><a href="#" class="active">Onglet actif</a></li>
|
||||
<li><a href="#">Liste 4</a></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="common">Tableaux</h2>
|
||||
<p>Il existe deux mises en forme type de tableaux selon que l'on cherche à faire un tableau ordinaire
|
||||
ou un tableau dont on peut déplacer les lignes par glisser déposer (voir plus bas). Cependant certaines règles
|
||||
sont communes à tout les tableaux.</p>
|
||||
|
||||
<h3>Règles communes</h3>
|
||||
<h4>Largeur du tableau</h4>
|
||||
<p>Sauf pour des tableaux particuliers (absents dans l'admin mais qui pourraient être nécessaires
|
||||
à un plugin,les tableaux occupent toute la largeur de la page. Afin que les tableaux soient consultables
|
||||
sur un mobile en navigant horizontalement, on englobe le tableau dans une <code>div class="table-outer"</code>,
|
||||
qui servira de « conteneur ».</p>
|
||||
<h4>Accessibilité</h4>
|
||||
<p>Les éléments caption, th, scope sont nécessaires à l'accessibilité. Ne les oubliez pas ! ».
|
||||
On peut utiliser la <code>class="hidden"</code> sur l'élément <code>caption</code> (qui accueille
|
||||
le titre du tableau) si vous ne souhaitez pas qu'il soit affiché sur la page.</p>
|
||||
<h4>Les classes</h4>
|
||||
<p>Des classes particulières peuvent être attribuées aux lignes :</p>
|
||||
<ul>
|
||||
<li><code>line</code> (systématique) : pour les traits horizontaux et le fond gris léger
|
||||
au survol ;</li>
|
||||
<li><code>offline</code> : pour un noir estompé (gris quoi).</li>
|
||||
</ul>
|
||||
<p>Des classes particulières peuvent être appliquées aux cellules :</p>
|
||||
<ul>
|
||||
<li><code>nowrap</code> : pas de retour à la ligne dans la cellule, quelle que soit la
|
||||
largeur de la page ;</li>
|
||||
<li><code>maximal</code> : la cellule prendra toute la largeur restante disponible ;</li>
|
||||
<li><code>count</code> : le contenu de la cellule sera aligné à droite avec un petit retrait.</li>
|
||||
</ul>
|
||||
<h3 id="courants">Tableau classique</h3>
|
||||
<div class="table-outer">
|
||||
<table>
|
||||
<caption class="hidden">Liste des publications</caption>
|
||||
<tr>
|
||||
<th colspan="2" class="first">Titre</th>
|
||||
<th scope="col">Date</th>
|
||||
<th scope="col">Catégorie</th>
|
||||
<th scope="col">Auteur</th>
|
||||
<th scope="col">Commentaires</th>
|
||||
<th scope="col">Rétroliens</th>
|
||||
<th scope="col">État</th>
|
||||
</tr>
|
||||
<tr class="line">
|
||||
<td class="nowrap"><input type="checkbox" name="name1" value="value1" /></td>
|
||||
<td class="maximal" scope="row"><a href="#">Mon cher Franck</a></td>
|
||||
<td class="nowrap count">06/08/2013 19:16</td>
|
||||
<td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>
|
||||
<td class="nowrap">kozlika</td><td class="nowrap count">4</td>
|
||||
<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>
|
||||
</tr>
|
||||
<tr class="line offline">
|
||||
<td class="nowrap"><input type="checkbox" name="name2" value="value2" /></td>
|
||||
<td class="maximal" scope="row"><a href="#">Dotclear 2.3.0</a></td>
|
||||
<td class="nowrap count">16/05/2011 22:29</td>
|
||||
<td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>
|
||||
<td class="nowrap">kozlika</td><td class="nowrap count">5</td>
|
||||
<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>
|
||||
</tr>
|
||||
<tr class="line">
|
||||
<td class="nowrap"><input type="checkbox" name="entries[]" value="2148" /></td>
|
||||
<td class="maximal" scope="row"><a href="#">Causons opéra au Tamm Bara</a></td>
|
||||
<td class="nowrap count">24/11/2009 23:10</td>
|
||||
<td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>
|
||||
<td class="nowrap">kozlika</td>
|
||||
<td class="nowrap count">4</td><td class="nowrap count">1</td>
|
||||
<td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> </td>
|
||||
</tr>
|
||||
<tr class="line">
|
||||
<td class="nowrap"><input type="checkbox" name="entries[]" value="2136" /></td>
|
||||
<td class="maximal" scope="row"><a href="#">Souffler six bougies</a></td>
|
||||
<td class="nowrap count">14/08/2009 00:00</td><td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>
|
||||
<td class="nowrap">kozlika</td>
|
||||
<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>
|
||||
</tr>
|
||||
<tr class="line">
|
||||
<td class="nowrap"><input type="checkbox" name="entries[]" value="2129" /></td>
|
||||
<td class="maximal" scope="row"><a href="#">Dotclear et grenadine, troisième édition</a></td>
|
||||
<td class="nowrap count">15/06/2009 07:39</td>
|
||||
<td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>
|
||||
<td class="nowrap">kozlika</td>
|
||||
<td class="nowrap count">9</td>
|
||||
<td class="nowrap count">1</td>
|
||||
<td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> </td>
|
||||
</tr>
|
||||
<tr class="line">
|
||||
<td class="nowrap"><input type="checkbox" name="entries[]" value="2111" /></td>
|
||||
<td class="maximal" scope="row"><a href="#">L'abc dotclear est né</a></td>
|
||||
<td class="nowrap count">19/03/2009 10:31</td><td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>
|
||||
<td class="nowrap">kozlika</td>
|
||||
<td class="nowrap count">1</td><td class="nowrap count">0</td>
|
||||
<td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h3 id="dragable">Tableau avec ordonnancement</h3>
|
||||
<p>Les tableaux permettant l'ordonnancement doivent offrir la possibilité d'effectuer le classement grâce à
|
||||
des inputs placés en début de ligne pour que le classement soit possible même lorsque cette fonctionnalité est
|
||||
désactivée (via les préférences utilisateurs, voire une désactivation complète du javascript dans le navigateur).</p>
|
||||
<div class="table-outer">
|
||||
<table class="maximal dragable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="3">Titre</th>
|
||||
<th>Date</th>
|
||||
<th>Auteur</th>
|
||||
<th>Commentaires</th>
|
||||
<th>Rétroliens</th>
|
||||
<th>État</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="pageslist">
|
||||
<tr class="line" id="p10899">
|
||||
<td class="nowrap handle minimal">
|
||||
<input type="text" size="2" name="order[10899]" maxlength="3" value="1" class="position" title="position de Mentions légales" />
|
||||
</td>
|
||||
<td class="nowrap">
|
||||
<input type="checkbox" name="entries[]" value="10899" title="Sélectionner cette page" />
|
||||
</td>
|
||||
<td class="maximal"><a href="#">Mentions légales</a>
|
||||
</td>
|
||||
<td class="nowrap">17/12/2008 07:35</td>
|
||||
<td class="nowrap">franck</td>
|
||||
<td class="nowrap">0</td>
|
||||
<td class="nowrap">0</td>
|
||||
<td class="nowrap status">
|
||||
<img alt="Publié" title="Publié" src="images/check-on.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="line" id="p10937">
|
||||
<td class="nowrap handle minimal">
|
||||
<input type="text" size="2" name="order[10937]" maxlength="3" value="2" class="position" title="position de Page active et cachée" />
|
||||
</td>
|
||||
<td class="nowrap">
|
||||
<input type="checkbox" name="entries[]" value="10937" title="Sélectionner cette page" />
|
||||
</td>
|
||||
<td class="maximal"><a href="#">Page active et cachée</a>
|
||||
</td>
|
||||
<td class="nowrap">26/10/2012 11:08</td>
|
||||
<td class="nowrap">admin</td>
|
||||
<td class="nowrap">0</td>
|
||||
<td class="nowrap">0</td>
|
||||
<td class="nowrap status">
|
||||
<img alt="Publié" title="Publié" src="images/check-on.png" />
|
||||
<img alt="Masqué" title="Masqué" src="images/hidden.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="line offline" id="p11047">
|
||||
<td class="nowrap handle minimal">
|
||||
<input type="text" size="2" name="order[11047]" maxlength="3" value="3" class="position" title="position de Page révisionnable" />
|
||||
</td>
|
||||
<td class="nowrap">
|
||||
<input type="checkbox" name="entries[]" value="11047" title="Sélectionner cette page" />
|
||||
</td>
|
||||
<td class="maximal"><a href="#">Page révisionnable</a>
|
||||
</td>
|
||||
<td class="nowrap">14/12/2012 13:26</td>
|
||||
<td class="nowrap">admin</td>
|
||||
<td class="nowrap">0</td>
|
||||
<td class="nowrap">0</td>
|
||||
<td class="nowrap status">
|
||||
<img alt="En attente" title="En attente" src="images/check-wrn.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="line offline" id="p10939">
|
||||
<td class="nowrap handle minimal">
|
||||
<input type="text" size="2" name="order[10939]" maxlength="3" value="4" class="position" title="position de Programme" />
|
||||
</td>
|
||||
<td class="nowrap">
|
||||
<input type="checkbox" name="entries[]" value="10939" title="Sélectionner cette page" />
|
||||
</td>
|
||||
<td class="maximal"><a href="#">Programme</a>
|
||||
</td>
|
||||
<td class="nowrap">26/10/2020 11:23</td>
|
||||
<td class="nowrap">admin</td>
|
||||
<td class="nowrap">0</td>
|
||||
<td class="nowrap">0</td>
|
||||
<td class="nowrap status">
|
||||
<img alt="Programmé" title="Programmé" src="images/scheduled.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="line offline" id="p10940">
|
||||
<td class="nowrap handle minimal">
|
||||
<input type="text" size="2" name="order[10940]" maxlength="3" value="5" class="position" title="position de Protégée" />
|
||||
</td>
|
||||
<td class="nowrap">
|
||||
<input type="checkbox" name="entries[]" value="10940" title="Sélectionner cette page" />
|
||||
</td>
|
||||
<td class="maximal"><a href="#">Protégée</a>
|
||||
</td>
|
||||
<td class="nowrap">26/10/2012 11:23</td>
|
||||
<td class="nowrap">admin</td>
|
||||
<td class="nowrap">0</td>
|
||||
<td class="nowrap">0</td>
|
||||
<td class="nowrap status">
|
||||
<img alt="En attente" title="En attente" src="images/check-wrn.png" />
|
||||
<img alt="Protégé" title="Protégé" src="images/locker.png" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2 id="iconset">Icônes</h2>
|
||||
<p>Les icônes utilisées dans l'administration sont présentes en deux formats 64*64px pour les grandes
|
||||
(qui sont affichées sur le tableau de bord si la page correspondante est choisie en favori par l'utilisateur) et
|
||||
16*16px pour les petits formats.</p>
|
||||
<p>La plupart sont dérivées de la fonte d'icônes <a href="https://www.elegantthemes.com/blog/resources/elegant-icon-font">Elegant Font</a>. Les autres sont des images vectorielles réalisées
|
||||
par la DC Team. Nous les avons nommées <em>Traviata</em>. La palette de couleurs utilisée est la suivante :</p>
|
||||
<p class="txt-center"><img src="images/palette-traviata.png" alt="palette des couleurs utilisées pour les icônes" /></p>
|
||||
<p class="txt-center">Bleu : #137bbb - Vert : #9ac123 - Rouge : #c44d58 - Bleu ciel : #a2cbe9 - Gris clair : #ececec -
|
||||
Gris moyen : #b2b2b2 - Gris foncé : #676e78.</p>
|
||||
</div><!-- /content -->
|
||||
</div><!-- /main -->
|
||||
<div id="main-menu">
|
||||
<ul><li class="pretty-title">Typographie
|
||||
<ul>
|
||||
<li><a href="#texte">Texte</a></li>
|
||||
<li><a href="#titres">Titres hx</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="pretty-title">Layouts
|
||||
<ul>
|
||||
<li><a href="#onglets">Onglets</a></li>
|
||||
<li><a href="#multi-colonnage">Multi-colonnage</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="pretty-title">Interactions
|
||||
<ul>
|
||||
<li><a href="#elements">Éléments de formulaire</a></li>
|
||||
<li><a href="#boutons">Boutons</a></li>
|
||||
<li><a href="#messages">Messages</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="pretty-title">Navigation
|
||||
<ul>
|
||||
<li><a href="#direct">Accès direct</a></li>
|
||||
<li><a href="#prevnext">Précédent, suivant</a></li>
|
||||
<li><a href="#pseudo-tabs">Pseudo-onglets</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="pretty-title">Tableaux
|
||||
<ul>
|
||||
<li><a href="#commons">Règles communes</a></li>
|
||||
<li><a href="#courants">Tableaux courants</a></li>
|
||||
<li><a href="#dragables">Tableaux ordonnancés</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="info vertical-separator">
|
||||
<p>Cette page vise à présenter les règles graphiques et conventions utilisées dans les pages de l'administration
|
||||
d'une installation Dotclear, à l'usage des contributeurs et développeurs d'extensions. Elle en est elle-même
|
||||
une illustration. L'observation de son code source peut donc servir de complément aux descriptions.</p>
|
||||
</div>
|
||||
</div><!-- /main-menu -->
|
||||
|
||||
<div id="footer">
|
||||
<a href="https://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>
|
||||
</div><!-- /footer -->
|
||||
<!--
|
||||
.
|
||||
,;:'`'::
|
||||
__||
|
||||
_____/LLLL\_
|
||||
\__________"|
|
||||
~^~^~^~^~^~^~^~^~^~
|
||||
-->
|
||||
</div><!-- /wrapper -->
|
||||
</body>
|
||||
</html>
|
||||
410
dotclear._no/admin/auth.php
Normal file
@ -0,0 +1,410 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*/
|
||||
|
||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
||||
|
||||
# If we have a session cookie, go to index.php
|
||||
if (isset($_SESSION['sess_user_id'])) {
|
||||
$core->adminurl->redirect('admin.home');
|
||||
}
|
||||
|
||||
# Loading locales for detected language
|
||||
# That's a tricky hack but it works ;)
|
||||
$dlang = http::getAcceptLanguage();
|
||||
$dlang = ($dlang == '' ? 'en' : $dlang);
|
||||
if ($dlang != 'en' && preg_match('/^[a-z]{2}(-[a-z]{2})?$/', $dlang)) {
|
||||
l10n::lang($dlang);
|
||||
l10n::set(dirname(__FILE__) . '/../locales/' . $dlang . '/main');
|
||||
}
|
||||
|
||||
if (defined('DC_ADMIN_URL')) {
|
||||
$page_url = DC_ADMIN_URL . $core->adminurl->get('admin.auth');
|
||||
} else {
|
||||
$page_url = http::getHost() . $_SERVER['REQUEST_URI'];
|
||||
}
|
||||
|
||||
$change_pwd = $core->auth->allowPassChange() && isset($_POST['new_pwd']) && isset($_POST['new_pwd_c']) && isset($_POST['login_data']);
|
||||
$login_data = !empty($_POST['login_data']) ? html::escapeHTML($_POST['login_data']) : null;
|
||||
$recover = $core->auth->allowPassChange() && !empty($_REQUEST['recover']);
|
||||
$safe_mode = !empty($_REQUEST['safe_mode']);
|
||||
$akey = $core->auth->allowPassChange() && !empty($_GET['akey']) ? $_GET['akey'] : null;
|
||||
$user_id = $user_pwd = $user_key = $user_email = null;
|
||||
$err = $msg = null;
|
||||
|
||||
# Auto upgrade
|
||||
if (empty($_GET) && empty($_POST)) {
|
||||
require dirname(__FILE__) . '/../inc/dbschema/upgrade.php';
|
||||
try {
|
||||
if (($changes = dcUpgrade::dotclearUpgrade($core)) !== false) {
|
||||
$msg = __('Dotclear has been upgraded.') . '<!-- ' . $changes . ' -->';
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$err = $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
# If we have POST login informations, go throug auth process
|
||||
if (!empty($_POST['user_id']) && !empty($_POST['user_pwd'])) {
|
||||
$user_id = !empty($_POST['user_id']) ? $_POST['user_id'] : null;
|
||||
$user_pwd = !empty($_POST['user_pwd']) ? $_POST['user_pwd'] : null;
|
||||
}
|
||||
# If we have COOKIE login informations, go throug auth process
|
||||
elseif (isset($_COOKIE['dc_admin']) && strlen($_COOKIE['dc_admin']) == 104) {
|
||||
# If we have a remember cookie, go through auth process with user_key
|
||||
$user_id = substr($_COOKIE['dc_admin'], 40);
|
||||
$user_id = @unpack('a32', @pack('H*', $user_id));
|
||||
if (is_array($user_id)) {
|
||||
$user_id = trim($user_id[1]);
|
||||
$user_key = substr($_COOKIE['dc_admin'], 0, 40);
|
||||
$user_pwd = null;
|
||||
} else {
|
||||
$user_id = null;
|
||||
}
|
||||
}
|
||||
|
||||
# Recover password
|
||||
if ($recover && !empty($_POST['user_id']) && !empty($_POST['user_email'])) {
|
||||
$user_id = !empty($_POST['user_id']) ? $_POST['user_id'] : null;
|
||||
$user_email = !empty($_POST['user_email']) ? html::escapeHTML($_POST['user_email']) : '';
|
||||
try
|
||||
{
|
||||
$recover_key = $core->auth->setRecoverKey($user_id, $user_email);
|
||||
|
||||
$subject = mail::B64Header('Dotclear ' . __('Password reset'));
|
||||
$message =
|
||||
__('Someone has requested to reset the password for the following site and username.') . "\n\n" .
|
||||
$page_url . "\n" . __('Username:') . ' ' . $user_id . "\n\n" .
|
||||
__('To reset your password visit the following address, otherwise just ignore this email and nothing will happen.') . "\n" .
|
||||
$page_url . '?akey=' . $recover_key;
|
||||
|
||||
$headers[] = 'From: ' . (defined('DC_ADMIN_MAILFROM') && DC_ADMIN_MAILFROM ? DC_ADMIN_MAILFROM : 'dotclear@local');
|
||||
$headers[] = 'Content-Type: text/plain; charset=UTF-8;';
|
||||
|
||||
mail::sendMail($user_email, $subject, $message, $headers);
|
||||
$msg = sprintf(__('The e-mail was sent successfully to %s.'), $user_email);
|
||||
} catch (Exception $e) {
|
||||
$err = $e->getMessage();
|
||||
}
|
||||
}
|
||||
# Send new password
|
||||
elseif ($akey) {
|
||||
try
|
||||
{
|
||||
$recover_res = $core->auth->recoverUserPassword($akey);
|
||||
|
||||
$subject = mb_encode_mimeheader('Dotclear ' . __('Your new password'), 'UTF-8', 'B');
|
||||
$message =
|
||||
__('Username:') . ' ' . $recover_res['user_id'] . "\n" .
|
||||
__('Password:') . ' ' . $recover_res['new_pass'] . "\n\n" .
|
||||
preg_replace('/\?(.*)$/', '', $page_url);
|
||||
|
||||
$headers[] = 'From: ' . (defined('DC_ADMIN_MAILFROM') && DC_ADMIN_MAILFROM ? DC_ADMIN_MAILFROM : 'dotclear@local');
|
||||
$headers[] = 'Content-Type: text/plain; charset=UTF-8;';
|
||||
|
||||
mail::sendMail($recover_res['user_email'], $subject, $message, $headers);
|
||||
$msg = __('Your new password is in your mailbox.');
|
||||
} catch (Exception $e) {
|
||||
$err = $e->getMessage();
|
||||
}
|
||||
}
|
||||
# Change password and retry to log
|
||||
elseif ($change_pwd) {
|
||||
try
|
||||
{
|
||||
$tmp_data = explode('/', $_POST['login_data']);
|
||||
if (count($tmp_data) != 3) {
|
||||
throw new Exception();
|
||||
}
|
||||
$data = [
|
||||
'user_id' => base64_decode($tmp_data[0]),
|
||||
'cookie_admin' => $tmp_data[1],
|
||||
'user_remember' => $tmp_data[2] == '1'
|
||||
];
|
||||
if ($data['user_id'] === false) {
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
# Check login informations
|
||||
$check_user = false;
|
||||
if (isset($data['cookie_admin']) && strlen($data['cookie_admin']) == 104) {
|
||||
$user_id = substr($data['cookie_admin'], 40);
|
||||
$user_id = @unpack('a32', @pack('H*', $user_id));
|
||||
if (is_array($user_id)) {
|
||||
$user_id = trim($data['user_id']);
|
||||
$user_key = substr($data['cookie_admin'], 0, 40);
|
||||
$check_user = $core->auth->checkUser($user_id, null, $user_key) === true;
|
||||
} else {
|
||||
$user_id = trim($user_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$core->auth->allowPassChange() || !$check_user) {
|
||||
$change_pwd = false;
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
if ($_POST['new_pwd'] != $_POST['new_pwd_c']) {
|
||||
throw new Exception(__("Passwords don't match"));
|
||||
}
|
||||
|
||||
if ($core->auth->checkUser($user_id, $_POST['new_pwd']) === true) {
|
||||
throw new Exception(__("You didn't change your password."));
|
||||
}
|
||||
|
||||
$cur = $core->con->openCursor($core->prefix . 'user');
|
||||
$cur->user_change_pwd = 0;
|
||||
$cur->user_pwd = $_POST['new_pwd'];
|
||||
$core->updUser($core->auth->userID(), $cur);
|
||||
|
||||
$core->session->start();
|
||||
$_SESSION['sess_user_id'] = $user_id;
|
||||
$_SESSION['sess_browser_uid'] = http::browserUID(DC_MASTER_KEY);
|
||||
|
||||
if ($data['user_remember']) {
|
||||
setcookie('dc_admin', $data['cookie_admin'], strtotime('+15 days'), '', '', DC_ADMIN_SSL);
|
||||
}
|
||||
|
||||
$core->adminurl->redirect('admin.home');
|
||||
} catch (Exception $e) {
|
||||
$err = $e->getMessage();
|
||||
}
|
||||
}
|
||||
# Try to log
|
||||
elseif ($user_id !== null && ($user_pwd !== null || $user_key !== null)) {
|
||||
# We check the user
|
||||
$check_user = $core->auth->checkUser($user_id, $user_pwd, $user_key, false) === true;
|
||||
if ($check_user) {
|
||||
$check_perms = $core->auth->findUserBlog() !== false;
|
||||
} else {
|
||||
$check_perms = false;
|
||||
}
|
||||
|
||||
$cookie_admin = http::browserUID(DC_MASTER_KEY . $user_id .
|
||||
$core->auth->cryptLegacy($user_id)) . bin2hex(pack('a32', $user_id));
|
||||
|
||||
if ($check_perms && $core->auth->mustChangePassword()) {
|
||||
$login_data = join('/', [
|
||||
base64_encode($user_id),
|
||||
$cookie_admin,
|
||||
empty($_POST['user_remember']) ? '0' : '1'
|
||||
]);
|
||||
|
||||
if (!$core->auth->allowPassChange()) {
|
||||
$err = __('You have to change your password before you can login.');
|
||||
} else {
|
||||
$err = __('In order to login, you have to change your password now.');
|
||||
$change_pwd = true;
|
||||
}
|
||||
} elseif ($check_perms && !empty($_POST['safe_mode']) && !$core->auth->isSuperAdmin()) {
|
||||
$err = __('Safe Mode can only be used for super administrators.');
|
||||
} elseif ($check_perms) {
|
||||
$core->session->start();
|
||||
$_SESSION['sess_user_id'] = $user_id;
|
||||
$_SESSION['sess_browser_uid'] = http::browserUID(DC_MASTER_KEY);
|
||||
|
||||
if (!empty($_POST['blog'])) {
|
||||
$_SESSION['sess_blog_id'] = $_POST['blog'];
|
||||
}
|
||||
|
||||
if (!empty($_POST['safe_mode']) && $core->auth->isSuperAdmin()) {
|
||||
$_SESSION['sess_safe_mode'] = true;
|
||||
}
|
||||
|
||||
if (!empty($_POST['user_remember'])) {
|
||||
setcookie('dc_admin', $cookie_admin, strtotime('+15 days'), '', '', DC_ADMIN_SSL);
|
||||
}
|
||||
|
||||
$core->adminurl->redirect('admin.home');
|
||||
} else {
|
||||
if (isset($_COOKIE['dc_admin'])) {
|
||||
unset($_COOKIE['dc_admin']);
|
||||
setcookie('dc_admin', false, -600, '', '', DC_ADMIN_SSL);
|
||||
}
|
||||
if ($check_user) {
|
||||
$err = __('Insufficient permissions');
|
||||
} else {
|
||||
$err = __('Wrong username or password');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET['user'])) {
|
||||
$user_id = $_GET['user'];
|
||||
}
|
||||
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
// Prevents Clickjacking as far as possible
|
||||
header('X-Frame-Options: SAMEORIGIN'); // FF 3.6.9+ Chrome 4.1+ IE 8+ Safari 4+ Opera 10.5+
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="<?php echo $dlang; ?>">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<meta http-equiv="Content-Style-Type" content="text/css" />
|
||||
<meta http-equiv="Content-Language" content="<?php echo $dlang; ?>" />
|
||||
<meta name="ROBOTS" content="NOARCHIVE,NOINDEX,NOFOLLOW" />
|
||||
<meta name="GOOGLEBOT" content="NOSNIPPET" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title><?php echo html::escapeHTML(DC_VENDOR_NAME); ?></title>
|
||||
<link rel="icon" type="image/png" href="images/favicon96-logout.png" />
|
||||
<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon" />
|
||||
|
||||
|
||||
<?php
|
||||
echo dcPage::jsCommon();
|
||||
?>
|
||||
|
||||
<link rel="stylesheet" href="style/default.css" type="text/css" media="screen" />
|
||||
|
||||
<?php
|
||||
# --BEHAVIOR-- loginPageHTMLHead
|
||||
$core->callBehavior('loginPageHTMLHead');
|
||||
|
||||
echo dcPage::jsLoad('js/_auth.js');
|
||||
?>
|
||||
</head>
|
||||
|
||||
<body id="dotclear-admin" class="auth">
|
||||
|
||||
<form action="<?php echo $core->adminurl->get('admin.auth'); ?>" method="post" id="login-screen">
|
||||
<h1 role="banner"><?php echo html::escapeHTML(DC_VENDOR_NAME); ?></h1>
|
||||
|
||||
<?php
|
||||
if ($err) {
|
||||
echo '<div class="error" role="alert">' . $err . '</div>';
|
||||
}
|
||||
if ($msg) {
|
||||
echo '<p class="success" role="alert">' . $msg . '</p>';
|
||||
}
|
||||
|
||||
if ($akey) {
|
||||
echo '<p><a href="' . $core->adminurl->get('admin.auth') . '">' . __('Back to login screen') . '</a></p>';
|
||||
} elseif ($recover) {
|
||||
echo
|
||||
'<div class="fieldset" role="main"><h2>' . __('Request a new password') . '</h2>' .
|
||||
'<p><label for="user_id">' . __('Username:') . '</label> ' .
|
||||
form::field('user_id', 20, 32,
|
||||
[
|
||||
'default' => html::escapeHTML($user_id),
|
||||
'autocomplete' => 'username'
|
||||
]
|
||||
) .
|
||||
'</p>' .
|
||||
|
||||
'<p><label for="user_email">' . __('Email:') . '</label> ' .
|
||||
form::email('user_email',
|
||||
[
|
||||
'default' => html::escapeHTML($user_email),
|
||||
'autocomplete' => 'email'
|
||||
]
|
||||
) .
|
||||
'</p>' .
|
||||
|
||||
'<p><input type="submit" value="' . __('recover') . '" />' .
|
||||
form::hidden('recover', 1) . '</p>' .
|
||||
'</div>' .
|
||||
|
||||
'<div id="issue">' .
|
||||
'<p><a href="' . $core->adminurl->get('admin.auth') . '">' . __('Back to login screen') . '</a></p>' .
|
||||
'</div>';
|
||||
} elseif ($change_pwd) {
|
||||
echo
|
||||
'<div class="fieldset"><h2>' . __('Change your password') . '</h2>' .
|
||||
'<p><label for="new_pwd">' . __('New password:') . '</label> ' .
|
||||
form::password('new_pwd', 20, 255,
|
||||
[
|
||||
'autocomplete' => 'new-password'
|
||||
]
|
||||
) . '</p>' .
|
||||
|
||||
'<p><label for="new_pwd_c">' . __('Confirm password:') . '</label> ' .
|
||||
form::password('new_pwd_c', 20, 255,
|
||||
[
|
||||
'autocomplete' => 'new-password'
|
||||
]
|
||||
) . '</p>' .
|
||||
'</div>' .
|
||||
|
||||
'<p><input type="submit" value="' . __('change') . '" />' .
|
||||
form::hidden('login_data', $login_data) . '</p>';
|
||||
} else {
|
||||
if (is_callable([$core->auth, 'authForm'])) {
|
||||
echo $core->auth->authForm($user_id);
|
||||
} else {
|
||||
if ($safe_mode) {
|
||||
echo '<div class="fieldset" role="main">';
|
||||
echo '<h2>' . __('Safe mode login') . '</h2>';
|
||||
echo
|
||||
'<p class="form-note">' .
|
||||
__('This mode allows you to login without activating any of your plugins. This may be useful to solve compatibility problems') . ' </p>' .
|
||||
'<p class="form-note">' . __('Disable or delete any plugin suspected to cause trouble, then log out and log back in normally.') .
|
||||
'</p>';
|
||||
} else {
|
||||
echo '<div class="fieldset" role="main">';
|
||||
}
|
||||
|
||||
echo
|
||||
'<p><label for="user_id">' . __('Username:') . '</label> ' .
|
||||
form::field('user_id', 20, 32,
|
||||
[
|
||||
'default' => html::escapeHTML($user_id),
|
||||
'autocomplete' => 'username'
|
||||
]
|
||||
) . '</p>' .
|
||||
|
||||
'<p><label for="user_pwd">' . __('Password:') . '</label> ' .
|
||||
form::password('user_pwd', 20, 255,
|
||||
[
|
||||
'autocomplete' => 'current-password'
|
||||
]
|
||||
) . '</p>' .
|
||||
|
||||
'<p>' .
|
||||
form::checkbox('user_remember', 1) .
|
||||
'<label for="user_remember" class="classic">' .
|
||||
__('Remember my ID on this device') . '</label></p>' .
|
||||
|
||||
'<p><input type="submit" value="' . __('log in') . '" class="login" /></p>';
|
||||
|
||||
if (!empty($_REQUEST['blog'])) {
|
||||
echo form::hidden('blog', html::escapeHTML($_REQUEST['blog']));
|
||||
}
|
||||
if ($safe_mode) {
|
||||
echo
|
||||
form::hidden('safe_mode', 1) .
|
||||
'</div>';
|
||||
} else {
|
||||
echo '</div>';
|
||||
}
|
||||
echo
|
||||
'<p id="cookie_help" class="error">' . __('You must accept cookies in order to use the private area.') . '</p>';
|
||||
|
||||
echo '<div id="issue">';
|
||||
|
||||
if ($safe_mode) {
|
||||
echo
|
||||
'<p><a href="' . $core->adminurl->get('admin.auth') . '" id="normal_mode_link">' . __('Get back to normal authentication') . '</a></p>';
|
||||
} else {
|
||||
echo '<p id="more"><strong>' . __('Connection issue?') . '</strong></p>';
|
||||
if ($core->auth->allowPassChange()) {
|
||||
echo '<p><a href="' . $core->adminurl->get('admin.auth', ['recover' => 1]) . '">' . __('I forgot my password') . '</a></p>';
|
||||
}
|
||||
echo '<p><a href="' . $core->adminurl->get('admin.auth', ['safe_mode' => 1]) . '" id="safe_mode_link">' . __('I want to log in in safe mode') . '</a></p>';
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
113
dotclear._no/admin/blog.php
Normal file
@ -0,0 +1,113 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*/
|
||||
|
||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
||||
|
||||
dcPage::checkSuper();
|
||||
|
||||
$blog_id = '';
|
||||
$blog_url = '';
|
||||
$blog_name = '';
|
||||
$blog_desc = '';
|
||||
|
||||
# Create a blog
|
||||
if (!isset($_POST['id']) && (isset($_POST['create']))) {
|
||||
$cur = $core->con->openCursor($core->prefix . 'blog');
|
||||
$blog_id = $cur->blog_id = $_POST['blog_id'];
|
||||
$blog_url = $cur->blog_url = $_POST['blog_url'];
|
||||
$blog_name = $cur->blog_name = $_POST['blog_name'];
|
||||
$blog_desc = $cur->blog_desc = $_POST['blog_desc'];
|
||||
|
||||
try
|
||||
{
|
||||
# --BEHAVIOR-- adminBeforeBlogCreate
|
||||
$core->callBehavior('adminBeforeBlogCreate', $cur, $blog_id);
|
||||
|
||||
$core->addBlog($cur);
|
||||
|
||||
# Default settings and override some
|
||||
$core->blogDefaults($cur->blog_id);
|
||||
$blog_settings = new dcSettings($core, $cur->blog_id);
|
||||
$blog_settings->addNamespace('system');
|
||||
$blog_settings->system->put('lang', $core->auth->getInfo('user_lang'));
|
||||
$blog_settings->system->put('blog_timezone', $core->auth->getInfo('user_tz'));
|
||||
|
||||
if (substr($blog_url, -1) == '?') {
|
||||
$blog_settings->system->put('url_scan', 'query_string');
|
||||
} else {
|
||||
$blog_settings->system->put('url_scan', 'path_info');
|
||||
}
|
||||
|
||||
# --BEHAVIOR-- adminAfterBlogCreate
|
||||
$core->callBehavior('adminAfterBlogCreate', $cur, $blog_id, $blog_settings);
|
||||
dcPage::addSuccessNotice(sprintf(__('Blog "%s" successfully created'), html::escapeHTML($cur->blog_name)));
|
||||
$core->adminurl->redirect("admin.blog", ['id' => $cur->blog_id]);
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_REQUEST['id'])) {
|
||||
$edit_blog_mode = true;
|
||||
include dirname(__FILE__) . '/blog_pref.php';
|
||||
} else {
|
||||
dcPage::open(__('New blog'), dcPage::jsConfirmClose('blog-form'),
|
||||
dcPage::breadcrumb(
|
||||
[
|
||||
__('System') => '',
|
||||
__('Blogs') => $core->adminurl->get("admin.blogs"),
|
||||
__('New blog') => ''
|
||||
])
|
||||
);
|
||||
|
||||
echo
|
||||
'<form action="' . $core->adminurl->get("admin.blog") . '" method="post" id="blog-form">' .
|
||||
|
||||
'<div>' . $core->formNonce() . '</div>' .
|
||||
'<p><label class="required" for="blog_id"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Blog ID:') . '</label> ' .
|
||||
form::field('blog_id', 30, 32,
|
||||
[
|
||||
'default' => html::escapeHTML($blog_id),
|
||||
'extra_html' => 'required placeholder="' . __('Blog ID') . '"'
|
||||
]
|
||||
) . '</p>' .
|
||||
'<p class="form-note">' . __('At least 2 characters using letters, numbers or symbols.') . '</p> ';
|
||||
|
||||
echo
|
||||
'<p><label class="required" for="blog_name"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Blog name:') . '</label> ' .
|
||||
form::field('blog_name', 30, 255,
|
||||
[
|
||||
'default' => html::escapeHTML($blog_name),
|
||||
'extra_html' => 'required placeholder="' . __('Blog name') . '" lang="' . $core->auth->getInfo('user_lang') . '" ' .
|
||||
'spellcheck="true"'
|
||||
]
|
||||
) . '</p>' .
|
||||
|
||||
'<p><label class="required" for="blog_url"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Blog URL:') . '</label> ' .
|
||||
form::url('blog_url',
|
||||
[
|
||||
'size' => 30,
|
||||
'default' => html::escapeHTML($blog_url),
|
||||
'extra_html' => 'required placeholder="' . __('Blog URL') . '"'
|
||||
]
|
||||
) . '</p>' .
|
||||
|
||||
'<p class="area"><label for="blog_desc">' . __('Blog description:') . '</label> ' .
|
||||
form::textarea('blog_desc', 60, 5,
|
||||
[
|
||||
'default' => html::escapeHTML($blog_desc),
|
||||
'extra_html' => 'lang="' . $core->auth->getInfo('user_lang') . '" spellcheck="true"'
|
||||
]) . '</p>' .
|
||||
|
||||
'<p><input type="submit" accesskey="s" name="create" value="' . __('Create') . '" /></p>' .
|
||||
'</form>';
|
||||
|
||||
dcPage::helpBlock('core_blog_new');
|
||||
dcPage::close();
|
||||
}
|
||||
74
dotclear._no/admin/blog_del.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*/
|
||||
|
||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
||||
|
||||
dcPage::checkSuper();
|
||||
|
||||
$blog_id = '';
|
||||
$blog_name = '';
|
||||
|
||||
if (!empty($_POST['blog_id'])) {
|
||||
try {
|
||||
$rs = $core->getBlog($_POST['blog_id']);
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
|
||||
if ($rs->isEmpty()) {
|
||||
$core->error->add(__('No such blog ID'));
|
||||
} else {
|
||||
$blog_id = $rs->blog_id;
|
||||
$blog_name = $rs->blog_name;
|
||||
}
|
||||
}
|
||||
|
||||
# Delete the blog
|
||||
if (!$core->error->flag() && $blog_id && !empty($_POST['del'])) {
|
||||
if (!$core->auth->checkPassword($_POST['pwd'])) {
|
||||
$core->error->add(__('Password verification failed'));
|
||||
} else {
|
||||
try {
|
||||
$core->delBlog($blog_id);
|
||||
dcPage::addSuccessNotice(sprintf(__('Blog "%s" successfully deleted'), html::escapeHTML($blog_name)));
|
||||
|
||||
$core->adminurl->redirect("admin.blogs");
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dcPage::open(__('Delete a blog'), '',
|
||||
dcPage::breadcrumb(
|
||||
[
|
||||
__('System') => '',
|
||||
__('Blogs') => $core->adminurl->get("admin.blogs"),
|
||||
__('Delete a blog') => ''
|
||||
])
|
||||
);
|
||||
|
||||
if (!$core->error->flag()) {
|
||||
echo
|
||||
'<div class="warning-msg"><p><strong>' . __('Warning') . '</strong></p>' .
|
||||
'<p>' . sprintf(__('You are about to delete the blog %s. Every entry, comment and category will be deleted.'),
|
||||
'<strong>' . $blog_id . ' (' . $blog_name . ')</strong>') . '</p></div>' .
|
||||
'<p>' . __('Please give your password to confirm the blog deletion.') . '</p>';
|
||||
|
||||
echo
|
||||
'<form action="' . $core->adminurl->get("admin.blog.del") . '" method="post">' .
|
||||
'<div>' . $core->formNonce() . '</div>' .
|
||||
'<p><label for="pwd">' . __('Your password:') . '</label> ' .
|
||||
form::password('pwd', 20, 255, ['autocomplete' => 'current-password']) . '</p>' .
|
||||
'<p><input type="submit" class="delete" name="del" value="' . __('Delete this blog') . '" />' .
|
||||
form::hidden('blog_id', $blog_id) . '</p>' .
|
||||
'</form>';
|
||||
}
|
||||
|
||||
dcPage::close();
|
||||
907
dotclear._no/admin/blog_pref.php
Normal file
@ -0,0 +1,907 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*/
|
||||
|
||||
$standalone = !isset($edit_blog_mode);
|
||||
|
||||
$blog_id = false;
|
||||
|
||||
if ($standalone) {
|
||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
||||
dcPage::check('admin');
|
||||
$blog_id = $core->blog->id;
|
||||
$blog_status = $core->blog->status;
|
||||
$blog_name = $core->blog->name;
|
||||
$blog_desc = $core->blog->desc;
|
||||
$blog_settings = $core->blog->settings;
|
||||
$blog_url = $core->blog->url;
|
||||
|
||||
$action = $core->adminurl->get("admin.blog.pref");
|
||||
$redir = $core->adminurl->get("admin.blog.pref");
|
||||
} else {
|
||||
dcPage::checkSuper();
|
||||
try
|
||||
{
|
||||
if (empty($_REQUEST['id'])) {
|
||||
throw new Exception(__('No given blog id.'));
|
||||
}
|
||||
$rs = $core->getBlog($_REQUEST['id']);
|
||||
|
||||
if (!$rs) {
|
||||
throw new Exception(__('No such blog.'));
|
||||
}
|
||||
|
||||
$blog_id = $rs->blog_id;
|
||||
$blog_status = $rs->blog_status;
|
||||
$blog_name = $rs->blog_name;
|
||||
$blog_desc = $rs->blog_desc;
|
||||
$blog_settings = new dcSettings($core, $blog_id);
|
||||
$blog_url = $rs->blog_url;
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
|
||||
$action = $core->adminurl->get("admin.blog");
|
||||
$redir = $core->adminurl->get("admin.blog", ['id' => "%s"], '&', true);
|
||||
}
|
||||
|
||||
# Language codes
|
||||
$lang_combo = dcAdminCombos::getAdminLangsCombo();
|
||||
|
||||
# Status combo
|
||||
$status_combo = dcAdminCombos::getBlogStatusescombo();
|
||||
|
||||
# Date format combo
|
||||
$now = time();
|
||||
$date_formats = $blog_settings->system->date_formats;
|
||||
$time_formats = $blog_settings->system->time_formats;
|
||||
$date_formats_combo = ['' => ''];
|
||||
foreach ($date_formats as $format) {
|
||||
$date_formats_combo[dt::str($format, $now)] = $format;
|
||||
}
|
||||
$time_formats_combo = ['' => ''];
|
||||
foreach ($time_formats as $format) {
|
||||
$time_formats_combo[dt::str($format, $now)] = $format;
|
||||
}
|
||||
|
||||
# URL scan modes
|
||||
$url_scan_combo = [
|
||||
'PATH_INFO' => 'path_info',
|
||||
'QUERY_STRING' => 'query_string'
|
||||
];
|
||||
|
||||
# Post URL combo
|
||||
$post_url_combo = [
|
||||
__('year/month/day/title') => '{y}/{m}/{d}/{t}',
|
||||
__('year/month/title') => '{y}/{m}/{t}',
|
||||
__('year/title') => '{y}/{t}',
|
||||
__('title') => '{t}',
|
||||
__('post id/title') => '{id}/{t}',
|
||||
__('post id') => '{id}'
|
||||
];
|
||||
if (!in_array($blog_settings->system->post_url_format, $post_url_combo)) {
|
||||
$post_url_combo[html::escapeHTML($blog_settings->system->post_url_format)] = html::escapeHTML($blog_settings->system->post_url_format);
|
||||
}
|
||||
|
||||
# Note title tag combo
|
||||
$note_title_tag_combo = [
|
||||
__('H4') => 0,
|
||||
__('H3') => 1,
|
||||
__('P') => 2
|
||||
];
|
||||
|
||||
# Image title combo
|
||||
$img_title_combo = [
|
||||
__('(none)') => '',
|
||||
__('Title') => 'Title ;; separator(, )',
|
||||
__('Title, Date') => 'Title ;; Date(%b %Y) ;; separator(, )',
|
||||
__('Title, Country, Date') => 'Title ;; Country ;; Date(%b %Y) ;; separator(, )',
|
||||
__('Title, City, Country, Date') => 'Title ;; City ;; Country ;; Date(%b %Y) ;; separator(, )'
|
||||
];
|
||||
if (!in_array($blog_settings->system->media_img_title_pattern, $img_title_combo)) {
|
||||
$img_title_combo[html::escapeHTML($blog_settings->system->media_img_title_pattern)] = html::escapeHTML($blog_settings->system->media_img_title_pattern);
|
||||
}
|
||||
|
||||
# Image default size combo
|
||||
$img_default_size_combo = [];
|
||||
try {
|
||||
$media = new dcMedia($core);
|
||||
$img_default_size_combo[__('original')] = 'o';
|
||||
foreach ($media->thumb_sizes as $code => $size) {
|
||||
$img_default_size_combo[__($size[2])] = $code;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
|
||||
# Image default alignment combo
|
||||
$img_default_alignment_combo = [
|
||||
__('None') => 'none',
|
||||
__('Left') => 'left',
|
||||
__('Right') => 'right',
|
||||
__('Center') => 'center'
|
||||
];
|
||||
|
||||
# Image default legend and title combo
|
||||
$img_default_legend_combo = [
|
||||
__('Legend and title') => 'legend',
|
||||
__('Title') => 'title',
|
||||
__('None') => 'none'
|
||||
];
|
||||
|
||||
# Robots policy options
|
||||
$robots_policy_options = [
|
||||
'INDEX,FOLLOW' => __("I would like search engines and archivers to index and archive my blog's content."),
|
||||
'INDEX,FOLLOW,NOARCHIVE' => __("I would like search engines and archivers to index but not archive my blog's content."),
|
||||
'NOINDEX,NOFOLLOW,NOARCHIVE' => __("I would like to prevent search engines and archivers from indexing or archiving my blog's content.")
|
||||
];
|
||||
|
||||
# jQuery available versions
|
||||
$jquery_root = dirname(__FILE__) . '/../inc/js/jquery';
|
||||
$jquery_versions_combo = [__('Default') . ' (' . DC_DEFAULT_JQUERY . ')' => ''];
|
||||
if (is_dir($jquery_root) && is_readable($jquery_root)) {
|
||||
if (($d = @dir($jquery_root)) !== false) {
|
||||
while (($entry = $d->read()) !== false) {
|
||||
if ($entry != '.' && $entry != '..' && substr($entry, 0, 1) != '.' && is_dir($jquery_root . '/' . $entry)) {
|
||||
if ($entry != DC_DEFAULT_JQUERY) {
|
||||
$jquery_versions_combo[$entry] = $entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Update a blog
|
||||
if ($blog_id && !empty($_POST) && $core->auth->check('admin', $blog_id)) {
|
||||
$cur = $core->con->openCursor($core->prefix . 'blog');
|
||||
$cur->blog_id = $_POST['blog_id'];
|
||||
$cur->blog_url = preg_replace('/\?+$/', '?', $_POST['blog_url']);
|
||||
$cur->blog_name = $_POST['blog_name'];
|
||||
$cur->blog_desc = $_POST['blog_desc'];
|
||||
|
||||
if ($core->auth->isSuperAdmin() && in_array($_POST['blog_status'], $status_combo)) {
|
||||
$cur->blog_status = (int) $_POST['blog_status'];
|
||||
}
|
||||
|
||||
$media_img_t_size = (integer) $_POST['media_img_t_size'];
|
||||
if ($media_img_t_size < 0) {$media_img_t_size = 100;}
|
||||
|
||||
$media_img_s_size = (integer) $_POST['media_img_s_size'];
|
||||
if ($media_img_s_size < 0) {$media_img_s_size = 240;}
|
||||
|
||||
$media_img_m_size = (integer) $_POST['media_img_m_size'];
|
||||
if ($media_img_m_size < 0) {$media_img_m_size = 448;}
|
||||
|
||||
$media_video_width = (integer) $_POST['media_video_width'];
|
||||
if ($media_video_width < 0) {$media_video_width = 400;}
|
||||
|
||||
$media_video_height = (integer) $_POST['media_video_height'];
|
||||
if ($media_video_height < 0) {$media_video_height = 300;}
|
||||
|
||||
$nb_post_for_home = abs((integer) $_POST['nb_post_for_home']);
|
||||
if ($nb_post_for_home < 1) {$nb_post_for_home = 1;}
|
||||
|
||||
$nb_post_per_page = abs((integer) $_POST['nb_post_per_page']);
|
||||
if ($nb_post_per_page < 1) {$nb_post_per_page = 1;}
|
||||
|
||||
$nb_post_per_feed = abs((integer) $_POST['nb_post_per_feed']);
|
||||
if ($nb_post_per_feed < 1) {$nb_post_per_feed = 1;}
|
||||
|
||||
$nb_comment_per_feed = abs((integer) $_POST['nb_comment_per_feed']);
|
||||
if ($nb_comment_per_feed < 1) {$nb_comment_per_feed = 1;}
|
||||
|
||||
try
|
||||
{
|
||||
if ($cur->blog_id != null && $cur->blog_id != $blog_id) {
|
||||
$rs = $core->getBlog($cur->blog_id);
|
||||
|
||||
if ($rs) {
|
||||
throw new Exception(__('This blog ID is already used.'));
|
||||
}
|
||||
}
|
||||
|
||||
# --BEHAVIOR-- adminBeforeBlogUpdate
|
||||
$core->callBehavior('adminBeforeBlogUpdate', $cur, $blog_id);
|
||||
|
||||
if (!preg_match('/^[a-z]{2}(-[a-z]{2})?$/', $_POST['lang'])) {
|
||||
throw new Exception(__('Invalid language code'));
|
||||
}
|
||||
|
||||
$core->updBlog($blog_id, $cur);
|
||||
|
||||
# --BEHAVIOR-- adminAfterBlogUpdate
|
||||
$core->callBehavior('adminAfterBlogUpdate', $cur, $blog_id);
|
||||
|
||||
if ($cur->blog_id != null && $cur->blog_id != $blog_id) {
|
||||
if ($blog_id == $core->blog->id) {
|
||||
$core->setBlog($cur->blog_id);
|
||||
$_SESSION['sess_blog_id'] = $cur->blog_id;
|
||||
$blog_settings = $core->blog->settings;
|
||||
} else {
|
||||
$blog_settings = new dcSettings($core, $cur->blog_id);
|
||||
}
|
||||
|
||||
$blog_id = $cur->blog_id;
|
||||
}
|
||||
|
||||
$blog_settings->addNameSpace('system');
|
||||
|
||||
$blog_settings->system->put('editor', $_POST['editor']);
|
||||
$blog_settings->system->put('copyright_notice', $_POST['copyright_notice']);
|
||||
$blog_settings->system->put('post_url_format', $_POST['post_url_format']);
|
||||
$blog_settings->system->put('lang', $_POST['lang']);
|
||||
$blog_settings->system->put('blog_timezone', $_POST['blog_timezone']);
|
||||
$blog_settings->system->put('date_format', $_POST['date_format']);
|
||||
$blog_settings->system->put('time_format', $_POST['time_format']);
|
||||
$blog_settings->system->put('comments_ttl', abs((integer) $_POST['comments_ttl']));
|
||||
$blog_settings->system->put('trackbacks_ttl', abs((integer) $_POST['trackbacks_ttl']));
|
||||
$blog_settings->system->put('allow_comments', !empty($_POST['allow_comments']));
|
||||
$blog_settings->system->put('allow_trackbacks', !empty($_POST['allow_trackbacks']));
|
||||
$blog_settings->system->put('comments_pub', empty($_POST['comments_pub']));
|
||||
$blog_settings->system->put('trackbacks_pub', empty($_POST['trackbacks_pub']));
|
||||
$blog_settings->system->put('comments_nofollow', !empty($_POST['comments_nofollow']));
|
||||
$blog_settings->system->put('wiki_comments', !empty($_POST['wiki_comments']));
|
||||
$blog_settings->system->put('comment_preview_optional', !empty($_POST['comment_preview_optional']));
|
||||
$blog_settings->system->put('enable_xmlrpc', !empty($_POST['enable_xmlrpc']));
|
||||
$blog_settings->system->put('note_title_tag', $_POST['note_title_tag']);
|
||||
$blog_settings->system->put('nb_post_for_home', $nb_post_for_home);
|
||||
$blog_settings->system->put('nb_post_per_page', $nb_post_per_page);
|
||||
$blog_settings->system->put('use_smilies', !empty($_POST['use_smilies']));
|
||||
$blog_settings->system->put('no_search', !empty($_POST['no_search']));
|
||||
$blog_settings->system->put('inc_subcats', !empty($_POST['inc_subcats']));
|
||||
$blog_settings->system->put('media_img_t_size', $media_img_t_size);
|
||||
$blog_settings->system->put('media_img_s_size', $media_img_s_size);
|
||||
$blog_settings->system->put('media_img_m_size', $media_img_m_size);
|
||||
$blog_settings->system->put('media_video_width', $media_video_width);
|
||||
$blog_settings->system->put('media_video_height', $media_video_height);
|
||||
$blog_settings->system->put('media_img_title_pattern', $_POST['media_img_title_pattern']);
|
||||
$blog_settings->system->put('media_img_use_dto_first', !empty($_POST['media_img_use_dto_first']));
|
||||
$blog_settings->system->put('media_img_no_date_alone', !empty($_POST['media_img_no_date_alone']));
|
||||
$blog_settings->system->put('media_img_default_size', $_POST['media_img_default_size']);
|
||||
$blog_settings->system->put('media_img_default_alignment', $_POST['media_img_default_alignment']);
|
||||
$blog_settings->system->put('media_img_default_link', !empty($_POST['media_img_default_link']));
|
||||
$blog_settings->system->put('media_img_default_legend', $_POST['media_img_default_legend']);
|
||||
$blog_settings->system->put('nb_post_per_feed', $nb_post_per_feed);
|
||||
$blog_settings->system->put('nb_comment_per_feed', $nb_comment_per_feed);
|
||||
$blog_settings->system->put('short_feed_items', !empty($_POST['short_feed_items']));
|
||||
if (isset($_POST['robots_policy'])) {
|
||||
$blog_settings->system->put('robots_policy', $_POST['robots_policy']);
|
||||
}
|
||||
$blog_settings->system->put('jquery_needed', !empty($_POST['jquery_needed']));
|
||||
$blog_settings->system->put('jquery_version', $_POST['jquery_version']);
|
||||
$blog_settings->system->put('prevents_clickjacking', !empty($_POST['prevents_clickjacking']));
|
||||
$blog_settings->system->put('static_home', !empty($_POST['static_home']));
|
||||
$blog_settings->system->put('static_home_url', $_POST['static_home_url']);
|
||||
|
||||
# --BEHAVIOR-- adminBeforeBlogSettingsUpdate
|
||||
$core->callBehavior('adminBeforeBlogSettingsUpdate', $blog_settings);
|
||||
|
||||
if ($core->auth->isSuperAdmin() && in_array($_POST['url_scan'], $url_scan_combo)) {
|
||||
$blog_settings->system->put('url_scan', $_POST['url_scan']);
|
||||
}
|
||||
dcPage::addSuccessNotice(__('Blog has been successfully updated.'));
|
||||
|
||||
http::redirect(sprintf($redir, $blog_id));
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Display
|
||||
|
||||
if ($standalone) {
|
||||
$breadcrumb = dcPage::breadcrumb(
|
||||
[
|
||||
html::escapeHTML($blog_name) => '',
|
||||
__('Blog settings') => ''
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$breadcrumb = dcPage::breadcrumb(
|
||||
[
|
||||
__('System') => '',
|
||||
__('Blogs') => $core->adminurl->get("admin.blogs"),
|
||||
__('Blog settings') . ' : ' . html::escapeHTML($blog_name) => ''
|
||||
]);
|
||||
}
|
||||
|
||||
$desc_editor = $core->auth->getOption('editor');
|
||||
$rte_flag = true;
|
||||
$rte_flags = @$core->auth->user_prefs->interface->rte_flags;
|
||||
if (is_array($rte_flags) && in_array('blog_descr', $rte_flags)) {
|
||||
$rte_flag = $rte_flags['blog_descr'];
|
||||
}
|
||||
|
||||
dcPage::open(__('Blog settings'),
|
||||
dcPage::jsJson('blog_pref', [
|
||||
'warning_path_info' => __('Warning: except for special configurations, it is generally advised to have a trailing "/" in your blog URL in PATH_INFO mode.'),
|
||||
'warning_query_string' => __('Warning: except for special configurations, it is generally advised to have a trailing "?" in your blog URL in QUERY_STRING mode.')
|
||||
]) .
|
||||
dcPage::jsConfirmClose('blog-form') .
|
||||
($rte_flag ? $core->callBehavior('adminPostEditor', $desc_editor['xhtml'], 'blog_desc', ['#blog_desc'], 'xhtml') : '') .
|
||||
dcPage::jsLoad('js/_blog_pref.js') .
|
||||
|
||||
# --BEHAVIOR-- adminBlogPreferencesHeaders
|
||||
$core->callBehavior('adminBlogPreferencesHeaders') .
|
||||
|
||||
dcPage::jsPageTabs(),
|
||||
$breadcrumb
|
||||
);
|
||||
|
||||
if ($blog_id) {
|
||||
if (!empty($_GET['add'])) {
|
||||
dcPage::success(__('Blog has been successfully created.'));
|
||||
}
|
||||
|
||||
if (!empty($_GET['upd'])) {
|
||||
dcPage::success(__('Blog has been successfully updated.'));
|
||||
}
|
||||
|
||||
echo
|
||||
'<div class="multi-part" id="params" title="' . __('Parameters') . '">' .
|
||||
'<div id="standard-pref"><h3>' . __('Blog parameters') . '</h3>' .
|
||||
'<form action="' . $action . '" method="post" id="blog-form">';
|
||||
|
||||
echo
|
||||
'<div class="fieldset"><h4>' . __('Blog details') . '</h4>' .
|
||||
$core->formNonce();
|
||||
|
||||
echo
|
||||
'<p><label for="blog_name" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Blog name:') . '</label>' .
|
||||
form::field('blog_name', 30, 255,
|
||||
[
|
||||
'default' => html::escapeHTML($blog_name),
|
||||
'extra_html' => 'required placeholder="' . __('Blog name') . ' lang="' . $blog_settings->system->lang .
|
||||
'" spellcheck="true"'
|
||||
]
|
||||
) . '</p>';
|
||||
|
||||
echo
|
||||
'<p class="area"><label for="blog_desc">' . __('Blog description:') . '</label>' .
|
||||
form::textarea('blog_desc', 60, 5,
|
||||
[
|
||||
'default' => html::escapeHTML($blog_desc),
|
||||
'extra_html' => 'lang="' . $blog_settings->system->lang . '" spellcheck="true"'
|
||||
]) . '</p>';
|
||||
|
||||
if ($core->auth->isSuperAdmin()) {
|
||||
echo
|
||||
'<p><label for="blog_status">' . __('Blog status:') . '</label>' .
|
||||
form::combo('blog_status', $status_combo, $blog_status) . '</p>';
|
||||
|
||||
} else {
|
||||
/*
|
||||
Only super admins can change the blog ID and URL, but we need to pass
|
||||
their values to the POST request via hidden html input values so as
|
||||
to allow admins to update other settings.
|
||||
Otherwise dcCore::getBlogCursor() throws an exception.
|
||||
*/
|
||||
echo
|
||||
form::hidden('blog_id', html::escapeHTML($blog_id)) .
|
||||
form::hidden('blog_url', html::escapeHTML($blog_url));
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
|
||||
echo
|
||||
'<div class="fieldset"><h4>' . __('Blog configuration') . '</h4>' .
|
||||
|
||||
'<p><label for="editor">' . __('Blog editor name:') . '</label>' .
|
||||
form::field('editor', 30, 255, html::escapeHTML($blog_settings->system->editor)) .
|
||||
'</p>' .
|
||||
|
||||
'<p><label for="lang">' . __('Default language:') . '</label>' .
|
||||
form::combo('lang', $lang_combo, $blog_settings->system->lang, 'l10n') .
|
||||
'</p>' .
|
||||
|
||||
'<p><label for="blog_timezone">' . __('Blog timezone:') . '</label>' .
|
||||
form::combo('blog_timezone', dt::getZones(true, true), html::escapeHTML($blog_settings->system->blog_timezone)) .
|
||||
'</p>' .
|
||||
|
||||
'<p><label for="copyright_notice">' . __('Copyright notice:') . '</label>' .
|
||||
form::field('copyright_notice', 30, 255,
|
||||
[
|
||||
'default' => html::escapeHTML($blog_settings->system->copyright_notice),
|
||||
'extra_html' => 'lang="' . $blog_settings->system->lang . '" spellcheck="true"'
|
||||
]) .
|
||||
'</p>' .
|
||||
|
||||
'</div>';
|
||||
|
||||
echo
|
||||
'<div class="fieldset"><h4>' . __('Comments and trackbacks') . '</h4>' .
|
||||
|
||||
'<div class="two-cols">' .
|
||||
|
||||
'<div class="col">' .
|
||||
'<p><label for="allow_comments" class="classic">' .
|
||||
form::checkbox('allow_comments', '1', $blog_settings->system->allow_comments) .
|
||||
__('Accept comments') . '</label></p>' .
|
||||
'<p><label for="comments_pub" class="classic">' .
|
||||
form::checkbox('comments_pub', '1', !$blog_settings->system->comments_pub) .
|
||||
__('Moderate comments') . '</label></p>' .
|
||||
'<p><label for="comments_ttl" class="classic">' . sprintf(__('Leave comments open for %s days') . '.',
|
||||
form::number('comments_ttl', [
|
||||
'min' => 0,
|
||||
'max' => 999,
|
||||
'default' => $blog_settings->system->comments_ttl]
|
||||
)) .
|
||||
'</label></p>' .
|
||||
'<p class="form-note">' . __('No limit: leave blank.') . '</p>' .
|
||||
'<p><label for="wiki_comments" class="classic">' .
|
||||
form::checkbox('wiki_comments', '1', $blog_settings->system->wiki_comments) .
|
||||
__('Wiki syntax for comments') . '</label></p>' .
|
||||
'<p><label for="comment_preview_optional" class="classic">' .
|
||||
form::checkbox('comment_preview_optional', '1', $blog_settings->system->comment_preview_optional) .
|
||||
__('Preview of comment before submit is not mandatory') . '</label></p>' .
|
||||
'</div>' .
|
||||
|
||||
'<div class="col">' .
|
||||
'<p><label for="allow_trackbacks" class="classic">' .
|
||||
form::checkbox('allow_trackbacks', '1', $blog_settings->system->allow_trackbacks) .
|
||||
__('Accept trackbacks') . '</label></p>' .
|
||||
'<p><label for="trackbacks_pub" class="classic">' .
|
||||
form::checkbox('trackbacks_pub', '1', !$blog_settings->system->trackbacks_pub) .
|
||||
__('Moderate trackbacks') . '</label></p>' .
|
||||
'<p><label for="trackbacks_ttl" class="classic">' . sprintf(__('Leave trackbacks open for %s days') . '.',
|
||||
form::number('trackbacks_ttl', [
|
||||
'min' => 0,
|
||||
'max' => 999,
|
||||
'default' => $blog_settings->system->trackbacks_ttl]
|
||||
)) .
|
||||
'</label></p>' .
|
||||
'<p class="form-note">' . __('No limit: leave blank.') . '</p>' .
|
||||
'<p><label for="comments_nofollow" class="classic">' .
|
||||
form::checkbox('comments_nofollow', '1', $blog_settings->system->comments_nofollow) .
|
||||
__('Add "nofollow" relation on comments and trackbacks links') . '</label></p>' .
|
||||
'</div>' .
|
||||
'<br class="clear" />' . //Opera sucks
|
||||
|
||||
'</div>' .
|
||||
'<br class="clear" />' . //Opera sucks
|
||||
'</div>';
|
||||
|
||||
echo
|
||||
'<div class="fieldset"><h4>' . __('Blog presentation') . '</h4>' .
|
||||
'<div class="two-cols">' .
|
||||
'<div class="col">' .
|
||||
'<p><label for="date_format">' . __('Date format:') . '</label> ' .
|
||||
form::field('date_format', 30, 255, html::escapeHTML($blog_settings->system->date_format)) .
|
||||
form::combo('date_format_select', $date_formats_combo, ['extra_html' => 'title="' . __('Pattern of date') . '"']) .
|
||||
'</p>' .
|
||||
'<p class="chosen form-note">' . __('Sample:') . ' ' . dt::str(html::escapeHTML($blog_settings->system->date_format)) . '</p>' .
|
||||
|
||||
'<p><label for="time_format">' . __('Time format:') . '</label>' .
|
||||
form::field('time_format', 30, 255, html::escapeHTML($blog_settings->system->time_format)) .
|
||||
form::combo('time_format_select', $time_formats_combo, ['extra_html' => 'title="' . __('Pattern of time') . '"']) .
|
||||
'</p>' .
|
||||
'<p class="chosen form-note">' . __('Sample:') . ' ' . dt::str(html::escapeHTML($blog_settings->system->time_format)) . '</p>' .
|
||||
|
||||
'<p><label for="use_smilies" class="classic">' .
|
||||
form::checkbox('use_smilies', '1', $blog_settings->system->use_smilies) .
|
||||
__('Display smilies on entries and comments') . '</label></p>' .
|
||||
|
||||
'<p><label for="no_search" class="classic">' .
|
||||
form::checkbox('no_search', '1', $blog_settings->system->no_search) .
|
||||
__('Disable internal search system') . '</label></p>' .
|
||||
|
||||
'</div>' .
|
||||
|
||||
'<div class="col">' .
|
||||
|
||||
'<p><label for="nb_post_for_home" class="classic">' . sprintf(__('Display %s entries on first page'),
|
||||
form::number('nb_post_for_home', [
|
||||
'min' => 1,
|
||||
'max' => 999,
|
||||
'default' => $blog_settings->system->nb_post_for_home]
|
||||
)) .
|
||||
'</label></p>' .
|
||||
|
||||
'<p><label for="nb_post_per_page" class="classic">' . sprintf(__('Display %s entries per page'),
|
||||
form::number('nb_post_per_page', [
|
||||
'min' => 1,
|
||||
'max' => 999,
|
||||
'default' => $blog_settings->system->nb_post_per_page]
|
||||
)) .
|
||||
'</label></p>' .
|
||||
|
||||
'<p><label for="nb_post_per_feed" class="classic">' . sprintf(__('Display %s entries per feed'),
|
||||
form::number('nb_post_per_feed', [
|
||||
'min' => 1,
|
||||
'max' => 999,
|
||||
'default' => $blog_settings->system->nb_post_per_feed]
|
||||
)) .
|
||||
'</label></p>' .
|
||||
|
||||
'<p><label for="nb_comment_per_feed" class="classic">' . sprintf(__('Display %s comments per feed'),
|
||||
form::number('nb_comment_per_feed', [
|
||||
'min' => 1,
|
||||
'max' => 999,
|
||||
'default' => $blog_settings->system->nb_comment_per_feed]
|
||||
)) .
|
||||
'</label></p>' .
|
||||
|
||||
'<p><label for="short_feed_items" class="classic">' .
|
||||
form::checkbox('short_feed_items', '1', $blog_settings->system->short_feed_items) .
|
||||
__('Truncate feeds') . '</label></p>' .
|
||||
|
||||
'<p><label for="inc_subcats" class="classic">' .
|
||||
form::checkbox('inc_subcats', '1', $blog_settings->system->inc_subcats) .
|
||||
__('Include sub-categories in category page and category posts feed') . '</label></p>' .
|
||||
'</div>' .
|
||||
'</div>' .
|
||||
'<br class="clear" />' . //Opera sucks
|
||||
|
||||
'<hr />' .
|
||||
|
||||
'<p><label for="static_home" class="classic">' .
|
||||
form::checkbox('static_home', '1', $blog_settings->system->static_home) .
|
||||
__('Display an entry as static home page') . '</label></p>' .
|
||||
|
||||
'<p><label for="static_home_url" class="classic">' . __('Entry URL (its content will be used for the static home page):') . '</label> ' .
|
||||
form::field('static_home_url', 30, 255, html::escapeHTML($blog_settings->system->static_home_url)) .
|
||||
' <button type="button" id="static_home_url_selector">' . __('Choose an entry') . '</button>' .
|
||||
'</p>' .
|
||||
'<p class="form-note">' . __('Leave empty to use the default presentation.') . '</p> ' .
|
||||
|
||||
'</div>';
|
||||
|
||||
echo
|
||||
'<div class="fieldset"><h4 id="medias-settings">' . __('Media and images') . '</h4>' .
|
||||
'<p class="form-note warning">' .
|
||||
__('Please note that if you change current settings bellow, they will now apply to all new images in the media manager.') .
|
||||
' ' . __('Be carefull if you share it with other blogs in your installation.') . '<br />' .
|
||||
__('Set -1 to use the default size, set 0 to ignore this thumbnail size (images only).') . '</p>' .
|
||||
|
||||
'<div class="two-cols">' .
|
||||
'<div class="col">' .
|
||||
'<h5>' . __('Generated image sizes (max dimension in pixels)') . '</h5>' .
|
||||
'<p class="field"><label for="media_img_t_size">' . __('Thumbnail') . '</label> ' .
|
||||
form::number('media_img_t_size', [
|
||||
'min' => -1,
|
||||
'max' => 999,
|
||||
'default' => $blog_settings->system->media_img_t_size
|
||||
]) .
|
||||
'</p>' .
|
||||
|
||||
'<p class="field"><label for="media_img_s_size">' . __('Small') . '</label> ' .
|
||||
form::number('media_img_s_size', [
|
||||
'min' => -1,
|
||||
'max' => 999,
|
||||
'default' => $blog_settings->system->media_img_s_size
|
||||
]) .
|
||||
'</p>' .
|
||||
|
||||
'<p class="field"><label for="media_img_m_size">' . __('Medium') . '</label> ' .
|
||||
form::number('media_img_m_size', [
|
||||
'min' => -1,
|
||||
'max' => 999,
|
||||
'default' => $blog_settings->system->media_img_m_size
|
||||
]) .
|
||||
'</p>' .
|
||||
|
||||
'<h5>' . __('Default size of the inserted video (in pixels)') . '</h5>' .
|
||||
'<p class="field"><label for="media_video_width">' . __('Width') . '</label> ' .
|
||||
form::number('media_video_width', [
|
||||
'min' => -1,
|
||||
'max' => 999,
|
||||
'default' => $blog_settings->system->media_video_width
|
||||
]) .
|
||||
'</p>' .
|
||||
|
||||
'<p class="field"><label for="media_video_height">' . __('Height') . '</label> ' .
|
||||
form::number('media_video_height', [
|
||||
'min' => -1,
|
||||
'max' => 999,
|
||||
'default' => $blog_settings->system->media_video_height
|
||||
]) .
|
||||
'</p>' .
|
||||
'</div>' .
|
||||
|
||||
'<div class="col">' .
|
||||
'<h5>' . __('Default image insertion attributes') . '</h5>' .
|
||||
'<p class="vertical-separator"><label for="media_img_title_pattern">' . __('Inserted image title') . '</label>' .
|
||||
form::combo('media_img_title_pattern', $img_title_combo, html::escapeHTML($blog_settings->system->media_img_title_pattern)) . '</p>' .
|
||||
'<p><label for="media_img_use_dto_first" class="classic">' .
|
||||
form::checkbox('media_img_use_dto_first', '1', $blog_settings->system->media_img_use_dto_first) .
|
||||
__('Use original media date if possible') . '</label></p>' .
|
||||
'<p><label for="media_img_no_date_alone" class="classic">' .
|
||||
form::checkbox('media_img_no_date_alone', '1', $blog_settings->system->media_img_no_date_alone) .
|
||||
__('Do not display date if alone in title') . '</label></p>' .
|
||||
'<p class="form-note info">' . __('It is retrieved from the picture\'s metadata.') . '</p>' .
|
||||
|
||||
'<p class="field vertical-separator"><label for="media_img_default_size">' . __('Size of inserted image:') . '</label>' .
|
||||
form::combo('media_img_default_size', $img_default_size_combo,
|
||||
(html::escapeHTML($blog_settings->system->media_img_default_size) != '' ? html::escapeHTML($blog_settings->system->media_img_default_size) : 'm')) .
|
||||
'</p>' .
|
||||
'<p class="field"><label for="media_img_default_alignment">' . __('Image alignment:') . '</label>' .
|
||||
form::combo('media_img_default_alignment', $img_default_alignment_combo, html::escapeHTML($blog_settings->system->media_img_default_alignment)) .
|
||||
'</p>' .
|
||||
'<p><label for="media_img_default_link">' .
|
||||
form::checkbox('media_img_default_link', '1', $blog_settings->system->media_img_default_link) .
|
||||
__('Insert a link to the original image') . '</label></p>' .
|
||||
'<p class="field"><label for="media_img_default_legend">' . __('Image legend and title:') . '</label>' .
|
||||
form::combo('media_img_default_legend', $img_default_legend_combo, html::escapeHTML($blog_settings->system->media_img_default_legend)) .
|
||||
'</p>' .
|
||||
'</div>' .
|
||||
'</div>' .
|
||||
'<br class="clear" />' . //Opera sucks
|
||||
|
||||
'</div>' .
|
||||
'</div>';
|
||||
|
||||
echo '<div id="advanced-pref"><h3>' . __('Advanced parameters') . '</h3>';
|
||||
|
||||
if ($core->auth->isSuperAdmin()) {
|
||||
echo '<div class="fieldset"><h4>' . __('Blog details') . '</h4>';
|
||||
echo
|
||||
'<p><label for="blog_id" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Blog ID:') . '</label>' .
|
||||
form::field('blog_id', 30, 32, html::escapeHTML($blog_id), '', '', false, 'required placeholder="' . __('Blog ID') . '"') . '</p>' .
|
||||
'<p class="form-note">' . __('At least 2 characters using letters, numbers or symbols.') . '</p> ' .
|
||||
'<p class="form-note warn">' . __('Please note that changing your blog ID may require changes in your public index.php file.') . '</p>';
|
||||
|
||||
echo
|
||||
'<p><label for="blog_url" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Blog URL:') . '</label>' .
|
||||
form::url('blog_url', [
|
||||
'size' => 50,
|
||||
'max' => 255,
|
||||
'default' => html::escapeHTML($blog_url),
|
||||
'extra_html' => 'required placeholder="' . __('Blog URL') . '"'
|
||||
]) .
|
||||
'</p>' .
|
||||
|
||||
'<p><label for="url_scan">' . __('URL scan method:') . '</label>' .
|
||||
form::combo('url_scan', $url_scan_combo, $blog_settings->system->url_scan) . '</p>';
|
||||
|
||||
try
|
||||
{
|
||||
# Test URL of blog by testing it's ATOM feed
|
||||
$file = $blog_url . $core->url->getURLFor('feed', 'atom');
|
||||
$path = '';
|
||||
$status = '404';
|
||||
$content = '';
|
||||
|
||||
$client = netHttp::initClient($file, $path);
|
||||
if ($client !== false) {
|
||||
$client->setTimeout(4);
|
||||
$client->setUserAgent($_SERVER['HTTP_USER_AGENT']);
|
||||
$client->get($path);
|
||||
$status = $client->getStatus();
|
||||
$content = $client->getContent();
|
||||
}
|
||||
if ($status != '200') {
|
||||
// Might be 404 (URL not found), 670 (blog not online), ...
|
||||
echo
|
||||
'<p class="form-note warn">' .
|
||||
sprintf(__('The URL of blog or the URL scan method might not be well set (<code>%s</code> return a <strong>%s</strong> status).'),
|
||||
html::escapeHTML($file), $status) .
|
||||
'</p>';
|
||||
} else {
|
||||
if (substr($content, 0, 6) != '<?xml ') {
|
||||
// Not well formed XML feed
|
||||
echo
|
||||
'<p class="form-note warn">' .
|
||||
sprintf(__('The URL of blog or the URL scan method might not be well set (<code>%s</code> does not return an ATOM feed).'),
|
||||
html::escapeHTML($file)) .
|
||||
'</p>';
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
echo
|
||||
'<div class="fieldset"><h4>' . __('Blog configuration') . '</h4>' .
|
||||
|
||||
'<p><label for="post_url_format">' . __('New post URL format:') . '</label>' .
|
||||
form::combo('post_url_format', $post_url_combo, html::escapeHTML($blog_settings->system->post_url_format)) .
|
||||
'</p>' .
|
||||
'<p class="chosen form-note">' . __('Sample:') . ' ' . $core->blog->getPostURL('', date('Y-m-d H:i:00', $now), __('Dotclear'), 42) . '</p>' .
|
||||
'</p>' .
|
||||
|
||||
'<p><label for="note_title_tag">' . __('HTML tag for the title of the notes on the blog:') . '</label>' .
|
||||
form::combo('note_title_tag', $note_title_tag_combo, $blog_settings->system->note_title_tag) .
|
||||
'</p>' .
|
||||
|
||||
'<p><label for="enable_xmlrpc" class="classic">' .
|
||||
form::checkbox('enable_xmlrpc', '1', $blog_settings->system->enable_xmlrpc) .
|
||||
__('Enable XML/RPC interface') . '</label>' . '</p>' .
|
||||
'<p class="form-note info">' . __('XML/RPC interface allows you to edit your blog with an external client.') . '</p>';
|
||||
|
||||
if ($blog_settings->system->enable_xmlrpc) {
|
||||
echo
|
||||
'<p>' . __('XML/RPC interface is active. You should set the following parameters on your XML/RPC client:') . '</p>' .
|
||||
'<ul>' .
|
||||
'<li>' . __('Server URL:') . ' <strong><code>' .
|
||||
sprintf(DC_XMLRPC_URL, $core->blog->url, $core->blog->id) .
|
||||
'</code></strong></li>' .
|
||||
'<li>' . __('Blogging system:') . ' <strong><code>Movable Type</code></strong></li>' .
|
||||
'<li>' . __('User name:') . ' <strong><code>' . $core->auth->userID() . '</code></strong></li>' .
|
||||
'<li>' . __('Password:') . ' <strong><code><' . __('your password') . '></code></strong></li>' .
|
||||
'<li>' . __('Blog ID:') . ' <strong><code>1</code></strong></li>' .
|
||||
'</ul>';
|
||||
}
|
||||
|
||||
echo
|
||||
'</div>';
|
||||
|
||||
// Search engines policies
|
||||
echo '<div class="fieldset"><h4>' . __('Search engines robots policy') . '</h4>';
|
||||
|
||||
$i = 0;
|
||||
foreach ($robots_policy_options as $k => $v) {
|
||||
echo '<p><label for="robots_policy-' . $i . '" class="classic">' .
|
||||
form::radio(['robots_policy', 'robots_policy-' . $i], $k, $blog_settings->system->robots_policy == $k) . ' ' . $v . '</label></p>';
|
||||
$i++;
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
|
||||
echo '<div class="fieldset"><h4>' . __('jQuery javascript library') . '</h4>' .
|
||||
|
||||
'<p><label for="jquery_needed" class="classic">' .
|
||||
form::checkbox('jquery_needed', '1', $blog_settings->system->jquery_needed) .
|
||||
__('Load the jQuery library') . '</label></p>' .
|
||||
|
||||
'<p><label for="jquery_version" class="classic">' . __('jQuery version to be loaded for this blog:') . '</label>' . ' ' .
|
||||
form::combo('jquery_version', $jquery_versions_combo, $blog_settings->system->jquery_version) .
|
||||
'</p>' .
|
||||
'<br class="clear" />' . //Opera sucks
|
||||
|
||||
'</div>';
|
||||
|
||||
echo '<div class="fieldset"><h4>' . __('Blog security') . '</h4>' .
|
||||
|
||||
'<p><label for="prevents_clickjacking" class="classic">' .
|
||||
form::checkbox('prevents_clickjacking', '1', $blog_settings->system->prevents_clickjacking) .
|
||||
__('Protect the blog from Clickjacking (see <a href="https://en.wikipedia.org/wiki/Clickjacking">Wikipedia</a>)') . '</label></p>' .
|
||||
'<br class="clear" />' . //Opera sucks
|
||||
|
||||
'</div>';
|
||||
|
||||
echo '</div>'; // End advanced
|
||||
|
||||
echo '<div id="plugins-pref"><h3>' . __('Plugins parameters') . '</h3>';
|
||||
|
||||
# --BEHAVIOR-- adminBlogPreferencesForm
|
||||
$core->callBehavior('adminBlogPreferencesForm', $core, $blog_settings);
|
||||
|
||||
echo '</div>'; // End 3rd party, aka plugins
|
||||
|
||||
echo
|
||||
'<p><input type="submit" accesskey="s" value="' . __('Save') . '" />' .
|
||||
(!$standalone ? form::hidden('id', $blog_id) : '') .
|
||||
'</p>' .
|
||||
'</form>';
|
||||
|
||||
if ($core->auth->isSuperAdmin() && $blog_id != $core->blog->id) {
|
||||
echo
|
||||
'<form action="' . $core->adminurl->get("admin.blog.del") . '" method="post">' .
|
||||
'<p><input type="submit" class="delete" value="' . __('Delete this blog') . '" />' .
|
||||
form::hidden(['blog_id'], $blog_id) .
|
||||
$core->formNonce() . '</p>' .
|
||||
'</form>';
|
||||
} else {
|
||||
if ($blog_id == $core->blog->id) {
|
||||
echo '<p class="message">' . __('The current blog cannot be deleted.') . '</p>';
|
||||
} else {
|
||||
echo '<p class="message">' . __('Only superadmin can delete a blog.') . '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
|
||||
#
|
||||
# Users on the blog (with permissions)
|
||||
|
||||
$blog_users = $core->getBlogPermissions($blog_id, $core->auth->isSuperAdmin());
|
||||
$perm_types = $core->auth->getPermissionsTypes();
|
||||
|
||||
echo
|
||||
'<div class="multi-part" id="users" title="' . __('Users') . '">' .
|
||||
'<h3 class="out-of-screen-if-js">' . __('Users on this blog') . '</h3>';
|
||||
|
||||
if (empty($blog_users)) {
|
||||
echo '<p>' . __('No users') . '</p>';
|
||||
} else {
|
||||
if ($core->auth->isSuperAdmin()) {
|
||||
$user_url_p = '<a href="' . $core->adminurl->get("admin.user", ['id' => '%1$s'], '&', true) . '">%1$s</a>';
|
||||
} else {
|
||||
$user_url_p = '%1$s';
|
||||
}
|
||||
|
||||
# Sort users list on user_id key
|
||||
dcUtils::lexicalKeySort($blog_users);
|
||||
|
||||
$post_type = $core->getPostTypes();
|
||||
$current_blog_id = $core->blog->id;
|
||||
if ($blog_id != $core->blog->id) {
|
||||
$core->setBlog($blog_id);
|
||||
}
|
||||
|
||||
echo '<div>';
|
||||
foreach ($blog_users as $k => $v) {
|
||||
if (count($v['p']) > 0) {
|
||||
echo
|
||||
'<div class="user-perm' . ($v['super'] ? ' user_super' : '') . '">' .
|
||||
'<h4>' . sprintf($user_url_p, html::escapeHTML($k)) .
|
||||
' (' . html::escapeHTML(dcUtils::getUserCN(
|
||||
$k, $v['name'], $v['firstname'], $v['displayname']
|
||||
)) . ')</h4>';
|
||||
|
||||
if ($core->auth->isSuperAdmin()) {
|
||||
echo
|
||||
'<p>' . __('Email:') . ' ' .
|
||||
($v['email'] != '' ? '<a href="mailto:' . $v['email'] . '">' . $v['email'] . '</a>' : __('(none)')) .
|
||||
'</p>';
|
||||
}
|
||||
|
||||
echo
|
||||
'<h5>' . __('Publications on this blog:') . '</h5>' .
|
||||
'<ul>';
|
||||
foreach ($post_type as $type => $pt_info) {
|
||||
$params = [
|
||||
'post_type' => $type,
|
||||
'user_id' => $k
|
||||
];
|
||||
echo '<li>' . sprintf(__('%1$s: %2$s'), __($pt_info['label']), $core->blog->getPosts($params, true)->f(0)) . '</li>';
|
||||
}
|
||||
echo
|
||||
'</ul>';
|
||||
|
||||
echo
|
||||
'<h5>' . __('Permissions:') . '</h5>' .
|
||||
'<ul>';
|
||||
if ($v['super']) {
|
||||
echo '<li class="user_super">' . __('Super administrator') . '<br />' .
|
||||
'<span class="form-note">' . __('All rights on all blogs.') . '</span></li>';
|
||||
} else {
|
||||
foreach ($v['p'] as $p => $V) {
|
||||
if (isset($perm_types[$p])) {
|
||||
echo '<li ' . ($p == 'admin' ? 'class="user_admin"' : '') . '>' . __($perm_types[$p]);
|
||||
} else {
|
||||
echo '<li>' . sprintf(__('[%s] (unreferenced permission)'), $p);
|
||||
}
|
||||
|
||||
if ($p == 'admin') {
|
||||
echo '<br /><span class="form-note">' . __('All rights on this blog.') . '</span>';
|
||||
}
|
||||
echo '</li>';
|
||||
}
|
||||
}
|
||||
echo
|
||||
'</ul>';
|
||||
|
||||
if (!$v['super'] && $core->auth->isSuperAdmin()) {
|
||||
echo
|
||||
'<form action="' . $core->adminurl->get('admin.user.actions') . '" method="post">' .
|
||||
'<p class="change-user-perm"><input type="submit" class="reset" value="' . __('Change permissions') . '" />' .
|
||||
form::hidden(['redir'], $core->adminurl->get("admin.blog.pref", ['id' => $k], '&')) .
|
||||
form::hidden(['action'], 'perms') .
|
||||
form::hidden(['users[]'], $k) .
|
||||
form::hidden(['blogs[]'], $blog_id) .
|
||||
$core->formNonce() .
|
||||
'</p>' .
|
||||
'</form>';
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
echo '</div>';
|
||||
if ($current_blog_id != $core->blog->id) {
|
||||
$core->setBlog($current_blog_id);
|
||||
}
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
dcPage::helpBlock('core_blog_pref');
|
||||
dcPage::close();
|
||||
250
dotclear._no/admin/blog_theme.php
Normal file
@ -0,0 +1,250 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*/
|
||||
|
||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
||||
|
||||
dcPage::check('admin');
|
||||
|
||||
# -- Loading themes --
|
||||
$core->themes = new dcThemes($core);
|
||||
$core->themes->loadModules($core->blog->themes_path, null);
|
||||
|
||||
# -- Page helper --
|
||||
$list = new adminThemesList(
|
||||
$core->themes,
|
||||
$core->blog->themes_path,
|
||||
$core->blog->settings->system->store_theme_url,
|
||||
!empty($_GET['nocache'])
|
||||
);
|
||||
adminThemesList::$distributed_modules = explode(',', DC_DISTRIB_THEMES);
|
||||
|
||||
# -- Theme screenshot --
|
||||
if (!empty($_GET['shot']) && $list->modules->moduleExists($_GET['shot'])) {
|
||||
|
||||
$f = path::real(empty($_GET['src']) ?
|
||||
$core->blog->themes_path . '/' . $_GET['shot'] . '/screenshot.jpg' :
|
||||
$core->blog->themes_path . '/' . $_GET['shot'] . '/' . path::clean($_GET['src'])
|
||||
);
|
||||
|
||||
if (!file_exists($f)) {
|
||||
$f = dirname(__FILE__) . '/images/noscreenshot.png';
|
||||
}
|
||||
|
||||
http::cache(array_merge([$f], get_included_files()));
|
||||
|
||||
header('Content-Type: ' . files::getMimeType($f));
|
||||
header('Content-Length: ' . filesize($f));
|
||||
readfile($f);
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
# -- Display module configuration page --
|
||||
if ($list->setConfiguration($core->blog->settings->system->theme)) {
|
||||
|
||||
# Get content before page headers
|
||||
include $list->includeConfiguration();
|
||||
|
||||
# Gather content
|
||||
$list->getConfiguration();
|
||||
|
||||
# Display page
|
||||
dcPage::open(__('Blog appearance'),
|
||||
dcPage::jsPageTabs() .
|
||||
|
||||
# --BEHAVIOR-- themesToolsHeaders
|
||||
$core->callBehavior('themesToolsHeaders', $core, true),
|
||||
|
||||
dcPage::breadcrumb(
|
||||
[
|
||||
html::escapeHTML($core->blog->name) => '',
|
||||
__('Blog appearance') => $list->getURL('', false),
|
||||
'<span class="page-title">' . __('Theme configuration') . '</span>' => ''
|
||||
])
|
||||
);
|
||||
|
||||
# Display previously gathered content
|
||||
$list->displayConfiguration();
|
||||
|
||||
dcPage::helpBlock('core_blog_theme_conf');
|
||||
dcPage::close();
|
||||
|
||||
# Stop reading code here
|
||||
return;
|
||||
}
|
||||
|
||||
# -- Execute actions --
|
||||
try {
|
||||
$list->doActions();
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
|
||||
# -- Page header --
|
||||
dcPage::open(__('Themes management'),
|
||||
dcPage::jsLoad('js/_blog_theme.js') .
|
||||
dcPage::jsPageTabs() .
|
||||
|
||||
# --BEHAVIOR-- themesToolsHeaders
|
||||
$core->callBehavior('themesToolsHeaders', $core, false),
|
||||
|
||||
dcPage::breadcrumb(
|
||||
[
|
||||
html::escapeHTML($core->blog->name) => '',
|
||||
'<span class="page-title">' . __('Blog appearance') . '</span>' => ''
|
||||
])
|
||||
);
|
||||
|
||||
# -- Display modules lists --
|
||||
if ($core->auth->isSuperAdmin()) {
|
||||
|
||||
if (!$core->error->flag()) {
|
||||
if (!empty($_GET['nocache'])) {
|
||||
dcPage::success(__('Manual checking of themes update done successfully.'));
|
||||
}
|
||||
}
|
||||
|
||||
# Updated modules from repo
|
||||
$modules = $list->store->get(true);
|
||||
if (!empty($modules)) {
|
||||
echo
|
||||
'<div class="multi-part" id="update" title="' . html::escapeHTML(__('Update themes')) . '">' .
|
||||
'<h3>' . html::escapeHTML(__('Update themes')) . '</h3>' .
|
||||
'<p>' . sprintf(
|
||||
__('There is one theme to update available from repository.', 'There are %s themes to update available from repository.', count($modules)),
|
||||
count($modules)
|
||||
) . '</p>';
|
||||
|
||||
$list
|
||||
->setList('theme-update')
|
||||
->setTab('themes')
|
||||
->setModules($modules)
|
||||
->displayModules(
|
||||
/*cols */['checkbox', 'name', 'sshot', 'desc', 'author', 'version', 'current_version', 'parent'],
|
||||
/* actions */['update', 'delete']
|
||||
);
|
||||
|
||||
echo
|
||||
'<p class="info vertical-separator">' . sprintf(
|
||||
__("Visit %s repository, the resources center for Dotclear."),
|
||||
'<a href="https://themes.dotaddict.org/galerie-dc2/">Dotaddict</a>'
|
||||
) .
|
||||
'</p>' .
|
||||
|
||||
'</div>';
|
||||
} else {
|
||||
echo
|
||||
'<form action="' . $list->getURL('', false) . '" method="get">' .
|
||||
'<p><input type="hidden" name="nocache" value="1" />' .
|
||||
'<input type="submit" value="' . __('Force checking update of themes') . '" /></p>' .
|
||||
'</form>';
|
||||
}
|
||||
}
|
||||
|
||||
# Activated modules
|
||||
$modules = $list->modules->getModules();
|
||||
if (!empty($modules)) {
|
||||
|
||||
echo
|
||||
'<div class="multi-part" id="themes" title="' . __('Installed themes') . '">' .
|
||||
'<h3>' . __('Installed themes') . '</h3>' .
|
||||
'<p class="more-info">' . __('You can configure and manage installed themes from this list.') . '</p>';
|
||||
|
||||
$list
|
||||
->setList('theme-activate')
|
||||
->setTab('themes')
|
||||
->setModules($modules)
|
||||
->displayModules(
|
||||
/* cols */['sshot', 'distrib', 'name', 'config', 'desc', 'author', 'version', 'parent'],
|
||||
/* actions */['select', 'behavior', 'deactivate', 'delete']
|
||||
);
|
||||
|
||||
echo
|
||||
'</div>';
|
||||
}
|
||||
|
||||
# Deactivated modules
|
||||
$modules = $list->modules->getDisabledModules();
|
||||
if (!empty($modules)) {
|
||||
|
||||
echo
|
||||
'<div class="multi-part" id="deactivate" title="' . __('Deactivated themes') . '">' .
|
||||
'<h3>' . __('Deactivated themes') . '</h3>' .
|
||||
'<p class="more-info">' . __('Deactivated themes are installed but not usable. You can activate them from here.') . '</p>';
|
||||
|
||||
$list
|
||||
->setList('theme-deactivate')
|
||||
->setTab('themes')
|
||||
->setModules($modules)
|
||||
->displayModules(
|
||||
/* cols */['name', 'distrib'],
|
||||
/* actions */['activate', 'delete']
|
||||
);
|
||||
|
||||
echo
|
||||
'</div>';
|
||||
}
|
||||
|
||||
if ($core->auth->isSuperAdmin() && $list->isWritablePath()) {
|
||||
|
||||
# New modules from repo
|
||||
$search = $list->getSearch();
|
||||
$modules = $search ? $list->store->search($search) : $list->store->get();
|
||||
|
||||
if (!empty($search) || !empty($modules)) {
|
||||
echo
|
||||
'<div class="multi-part" id="new" title="' . __('Add themes') . '">' .
|
||||
'<h3>' . __('Add themes from repository') . '</h3>';
|
||||
// '<p>'.__('Search and install themes directly from repository.').'</p>';
|
||||
|
||||
$list
|
||||
->setList('theme-new')
|
||||
->setTab('new')
|
||||
->setModules($modules)
|
||||
->displaySearch()
|
||||
->displayIndex()
|
||||
->displayModules(
|
||||
/* cols */['expander', 'sshot', 'name', 'score', 'config', 'desc', 'author', 'version', 'parent', 'details', 'support'],
|
||||
/* actions */['install'],
|
||||
/* nav limit */true
|
||||
);
|
||||
|
||||
echo
|
||||
'<p class="info vertical-separator">' . sprintf(
|
||||
__("Visit %s repository, the resources center for Dotclear."),
|
||||
'<a href="https://themes.dotaddict.org/galerie-dc2/">Dotaddict</a>'
|
||||
) .
|
||||
'</p>' .
|
||||
|
||||
'</div>';
|
||||
}
|
||||
|
||||
# Add a new plugin
|
||||
echo
|
||||
'<div class="multi-part" id="addtheme" title="' . __('Install or upgrade manually') . '">' .
|
||||
'<h3>' . __('Add themes from a package') . '</h3>' .
|
||||
'<p class="more-info">' . __('You can install themes by uploading or downloading zip files.') . '</p>';
|
||||
|
||||
$list->displayManualForm();
|
||||
|
||||
echo
|
||||
'</div>';
|
||||
}
|
||||
|
||||
# --BEHAVIOR-- themesToolsTabs
|
||||
$core->callBehavior('themesToolsTabs', $core);
|
||||
|
||||
# -- Notice for super admin --
|
||||
if ($core->auth->isSuperAdmin() && !$list->isWritablePath()) {
|
||||
echo
|
||||
'<p class="warning">' . __('Some functions are disabled, please give write access to your themes directory to enable them.') . '</p>';
|
||||
}
|
||||
|
||||
dcPage::helpBlock('core_blog_theme');
|
||||
dcPage::close();
|
||||
185
dotclear._no/admin/blogs.php
Normal file
@ -0,0 +1,185 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*/
|
||||
|
||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
||||
|
||||
dcPage::check('usage,contentadmin');
|
||||
|
||||
# Filters
|
||||
$status_combo = array_merge(
|
||||
['-' => ''],
|
||||
dcAdminCombos::getBlogStatusesCombo()
|
||||
);
|
||||
|
||||
$sortby_combo = [
|
||||
__('Last update') => 'blog_upddt',
|
||||
__('Blog name') => 'UPPER(blog_name)',
|
||||
__('Blog ID') => 'B.blog_id',
|
||||
__('Status') => 'blog_status'
|
||||
];
|
||||
|
||||
$order_combo = [
|
||||
__('Descending') => 'desc',
|
||||
__('Ascending') => 'asc'
|
||||
];
|
||||
|
||||
# Actions
|
||||
|
||||
if ($core->auth->isSuperAdmin()) {
|
||||
$blogs_actions_page = new dcBlogsActionsPage($core, $core->adminurl->get("admin.blogs"));
|
||||
if ($blogs_actions_page->process()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Requests
|
||||
$q = !empty($_GET['q']) ? $_GET['q'] : '';
|
||||
$status = isset($_GET['status']) ? $_GET['status'] : '';
|
||||
$sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'blog_upddt';
|
||||
$order = !empty($_GET['order']) ? $_GET['order'] : 'desc';
|
||||
|
||||
$show_filters = false;
|
||||
|
||||
$page = !empty($_GET['page']) ? max(1, (integer) $_GET['page']) : 1;
|
||||
$nb_per_page = 30;
|
||||
|
||||
if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) {
|
||||
if ($nb_per_page != (integer) $_GET['nb']) {
|
||||
$show_filters = true;
|
||||
}
|
||||
$nb_per_page = (integer) $_GET['nb'];
|
||||
}
|
||||
|
||||
# - Search filter
|
||||
if ($q) {
|
||||
$params['q'] = $q;
|
||||
$show_filters = true;
|
||||
}
|
||||
|
||||
# - Status filter
|
||||
if ($status !== '' && in_array($status, $status_combo, true)) {
|
||||
$params['blog_status'] = $status;
|
||||
$show_filters = true;
|
||||
} else {
|
||||
$status = '';
|
||||
}
|
||||
|
||||
# - Sortby and order filter
|
||||
if ($sortby !== '' && in_array($sortby, $sortby_combo, true)) {
|
||||
if ($order !== '' && in_array($order, $order_combo, true)) {
|
||||
$params['order'] = $sortby . ' ' . $order;
|
||||
} else {
|
||||
$order = 'desc';
|
||||
}
|
||||
} else {
|
||||
$sortby = 'blog_upddt';
|
||||
$order = 'desc';
|
||||
}
|
||||
if ($sortby != 'blog_upddt' || $order != 'desc') {
|
||||
$show_filters = true;
|
||||
}
|
||||
|
||||
$params['limit'] = [(($page - 1) * $nb_per_page), $nb_per_page];
|
||||
|
||||
try {
|
||||
$counter = $core->getBlogs($params, 1);
|
||||
$rs = $core->getBlogs($params);
|
||||
$nb_blog = $counter->f(0);
|
||||
$rsStatic = $rs->toStatic();
|
||||
if (($sortby != 'blog_upddt') && ($sortby != 'blog_status')) {
|
||||
// Sort blog list using lexical order if necessary
|
||||
$rsStatic->extend('rsExtUser');
|
||||
$rsStatic = $rsStatic->toExtStatic();
|
||||
$rsStatic->lexicalSort(($sortby == 'UPPER(blog_name)' ? 'blog_name' : 'blog_id'), $order);
|
||||
}
|
||||
$blog_list = new adminBlogList($core, $rs, $counter->f(0));
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
|
||||
/* DISPLAY
|
||||
-------------------------------------------------------- */
|
||||
|
||||
dcPage::open(__('List of blogs'),
|
||||
dcPage::jsLoad('js/_blogs.js') . dcPage::jsFilterControl($show_filters),
|
||||
dcPage::breadcrumb(
|
||||
[
|
||||
__('System') => '',
|
||||
__('List of blogs') => ''
|
||||
])
|
||||
);
|
||||
|
||||
if (!$core->error->flag()) {
|
||||
if ($core->auth->isSuperAdmin()) {
|
||||
echo '<p class="top-add"><a class="button add" href="' . $core->adminurl->get("admin.blog") . '">' . __('Create a new blog') . '</a></p>';
|
||||
}
|
||||
|
||||
echo
|
||||
'<form action="' . $core->adminurl->get("admin.blogs") . '" method="get" id="filters-form">' .
|
||||
'<h3 class="out-of-screen-if-js">' . __('Show filters and display options') . '</h3>' .
|
||||
|
||||
'<div class="table">' .
|
||||
'<div class="cell">' .
|
||||
'<h4>' . __('Filters') . '</h4>' .
|
||||
'<p><label for="q" class="ib">' . __('Search:') . '</label> ' .
|
||||
form::field('q', 20, 255, html::escapeHTML($q)) . '</p>' .
|
||||
($core->auth->isSuperAdmin() ?
|
||||
'<p><label for="status" class="ib">' . __('Status:') . '</label> ' .
|
||||
form::combo('status', $status_combo, $status) . '</p>' : '') .
|
||||
'</div>' .
|
||||
|
||||
'<div class="cell filters-options">' .
|
||||
'<h4>' . __('Display options') . '</h4>' .
|
||||
'<p><label for="sortby" class="ib">' . __('Order by:') . '</label> ' .
|
||||
form::combo('sortby', $sortby_combo, html::escapeHTML($sortby)) . '</p>' .
|
||||
'<p><label for="order" class="ib">' . __('Sort:') . '</label> ' .
|
||||
form::combo('order', $order_combo, html::escapeHTML($order)) . '</p>' .
|
||||
'<p><span class="label ib">' . __('Show') . '</span> <label for="nb" class="classic">' .
|
||||
form::number('nb', 0, 999, $nb_per_page) . ' ' . __('blogs per page') . '</label></p>' .
|
||||
'</div>' .
|
||||
'</div>' .
|
||||
|
||||
'<p><input type="submit" value="' . __('Apply filters and display options') . '" />' .
|
||||
'<br class="clear" /></p>' . //Opera sucks
|
||||
'</form>';
|
||||
|
||||
# Show blogs
|
||||
$blog_list->display($page, $nb_per_page,
|
||||
($core->auth->isSuperAdmin() ?
|
||||
'<form action="' . $core->adminurl->get("admin.blogs") . '" method="post" id="form-blogs">' : '') .
|
||||
|
||||
'%s' .
|
||||
|
||||
($core->auth->isSuperAdmin() ?
|
||||
'<div class="two-cols clearfix">' .
|
||||
'<p class="col checkboxes-helpers"></p>' .
|
||||
|
||||
'<p class="col right"><label for="action" class="classic">' . __('Selected blogs action:') . '</label> ' .
|
||||
form::combo('action', $blogs_actions_page->getCombo(),
|
||||
['class' => 'online', 'extra_html' => 'title="' . __('Actions') . '"']) .
|
||||
$core->formNonce() .
|
||||
'<input id="do-action" type="submit" value="' . __('ok') . '" /></p>' .
|
||||
'</div>' .
|
||||
|
||||
'<p><label for="pwd" class="classic">' . __('Please give your password to confirm blog(s) deletion:') . '</label> ' .
|
||||
form::password('pwd', 20, 255, ['autocomplete' => 'current-password']) . '</p>' .
|
||||
|
||||
form::hidden(['sortby'], $sortby) .
|
||||
form::hidden(['order'], $order) .
|
||||
form::hidden(['status'], $status) .
|
||||
form::hidden(['page'], $page) .
|
||||
form::hidden(['nb'], $nb_per_page) .
|
||||
|
||||
'</form>' : ''),
|
||||
$show_filters
|
||||
);
|
||||
}
|
||||
|
||||
dcPage::helpBlock('core_blogs');
|
||||
dcPage::close();
|
||||
219
dotclear._no/admin/categories.php
Normal file
@ -0,0 +1,219 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*/
|
||||
|
||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
||||
|
||||
dcPage::check('categories');
|
||||
|
||||
# Remove a categories
|
||||
if (!empty($_POST['delete'])) {
|
||||
$keys = array_keys($_POST['delete']);
|
||||
$cat_id = (int) $keys[0];
|
||||
|
||||
# Check if category to delete exists
|
||||
$c = $core->blog->getCategory((integer) $cat_id);
|
||||
if ($c->isEmpty()) {
|
||||
dcPage::addErrorNotice(__('This category does not exist.'));
|
||||
$core->adminurl->redirect("admin.categories");
|
||||
}
|
||||
$name = $c->cat_title;
|
||||
unset($c);
|
||||
|
||||
try {
|
||||
# Delete category
|
||||
$core->blog->delCategory($cat_id);
|
||||
dcPage::addSuccessNotice(sprintf(__('The category "%s" has been successfully deleted.'), html::escapeHTML($name)));
|
||||
$core->adminurl->redirect("admin.categories");
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
# move post into a category
|
||||
if (!empty($_POST['mov']) && !empty($_POST['mov_cat'])) {
|
||||
try {
|
||||
# Check if category where to move posts exists
|
||||
$keys = array_keys($_POST['mov']);
|
||||
$cat_id = (int) $keys[0];
|
||||
$mov_cat = (int) $_POST['mov_cat'][$cat_id];
|
||||
|
||||
$mov_cat = $mov_cat ?: null;
|
||||
if ($mov_cat !== null) {
|
||||
$c = $core->blog->getCategory($mov_cat);
|
||||
if ($c->isEmpty()) {
|
||||
throw new Exception(__('Category where to move entries does not exist'));
|
||||
}
|
||||
$name = $c->cat_title;
|
||||
unset($c);
|
||||
}
|
||||
# Move posts
|
||||
if ($mov_cat != $cat_id) {
|
||||
$core->blog->changePostsCategory($cat_id, $mov_cat);
|
||||
}
|
||||
dcPage::addSuccessNotice(sprintf(__('The entries have been successfully moved to category "%s"'),
|
||||
html::escapeHTML($name)));
|
||||
$core->adminurl->redirect("admin.categories");
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
# Update order
|
||||
if (!empty($_POST['save_order']) && !empty($_POST['categories_order'])) {
|
||||
$categories = json_decode($_POST['categories_order']);
|
||||
|
||||
foreach ($categories as $category) {
|
||||
if (!empty($category->item_id) && !empty($category->left) && !empty($category->right)) {
|
||||
$core->blog->updCategoryPosition($category->item_id, $category->left, $category->right);
|
||||
}
|
||||
}
|
||||
|
||||
dcPage::addSuccessNotice(__('Categories have been successfully reordered.'));
|
||||
$core->adminurl->redirect("admin.categories");
|
||||
}
|
||||
|
||||
# Reset order
|
||||
if (!empty($_POST['reset'])) {
|
||||
try
|
||||
{
|
||||
$core->blog->resetCategoriesOrder();
|
||||
dcPage::addSuccessNotice(__('Categories order has been successfully reset.'));
|
||||
$core->adminurl->redirect("admin.categories");
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/* Display
|
||||
-------------------------------------------------------- */
|
||||
$rs = $core->blog->getCategories();
|
||||
|
||||
$starting_script = "";
|
||||
|
||||
$core->auth->user_prefs->addWorkspace('accessibility');
|
||||
if (!$core->auth->user_prefs->accessibility->nodragdrop
|
||||
&& $core->auth->check('categories', $core->blog->id)
|
||||
&& $rs->count() > 1) {
|
||||
$starting_script .= dcPage::jsLoad('js/jquery/jquery-ui.custom.js');
|
||||
$starting_script .= dcPage::jsLoad('js/jquery/jquery.ui.touch-punch.js');
|
||||
$starting_script .= dcPage::jsLoad('js/jquery/jquery.mjs.nestedSortable.js');
|
||||
}
|
||||
$starting_script .= dcPage::jsConfirmClose('form-categories');
|
||||
$starting_script .= dcPage::jsLoad('js/_categories.js');
|
||||
|
||||
dcPage::open(__('Categories'), $starting_script,
|
||||
dcPage::breadcrumb(
|
||||
[
|
||||
html::escapeHTML($core->blog->name) => '',
|
||||
__('Categories') => ''
|
||||
])
|
||||
);
|
||||
|
||||
if (!empty($_GET['del'])) {
|
||||
dcPage::success(__('The category has been successfully removed.'));
|
||||
}
|
||||
if (!empty($_GET['reord'])) {
|
||||
dcPage::success(__('Categories have been successfully reordered.'));
|
||||
}
|
||||
if (!empty($_GET['move'])) {
|
||||
dcPage::success(__('Entries have been successfully moved to the category you choose.'));
|
||||
}
|
||||
|
||||
$categories_combo = dcAdminCombos::getCategoriesCombo($rs);
|
||||
|
||||
echo
|
||||
'<p class="top-add"><a class="button add" href="' . $core->adminurl->get("admin.category") . '">' . __('New category') . '</a></p>';
|
||||
|
||||
echo
|
||||
'<div class="col">';
|
||||
if ($rs->isEmpty()) {
|
||||
echo '<p>' . __('No category so far.') . '</p>';
|
||||
} else {
|
||||
echo
|
||||
'<form action="' . $core->adminurl->get("admin.categories") . '" method="post" id="form-categories">' .
|
||||
'<div id="categories">';
|
||||
|
||||
$ref_level = $level = $rs->level - 1;
|
||||
while ($rs->fetch()) {
|
||||
$attr = 'id="cat_' . $rs->cat_id . '" class="cat-line clearfix"';
|
||||
|
||||
if ($rs->level > $level) {
|
||||
echo str_repeat('<ul><li ' . $attr . '>', $rs->level - $level);
|
||||
} elseif ($rs->level < $level) {
|
||||
echo str_repeat('</li></ul>', -($rs->level - $level));
|
||||
}
|
||||
|
||||
if ($rs->level <= $level) {
|
||||
echo '</li><li ' . $attr . '>';
|
||||
}
|
||||
|
||||
echo
|
||||
'<p class="cat-title"><label class="classic" for="cat_' . $rs->cat_id . '"><a href="' .
|
||||
$core->adminurl->get("admin.category", ['id' => $rs->cat_id]) . '">' . html::escapeHTML($rs->cat_title) .
|
||||
'</a></label> </p>' .
|
||||
'<p class="cat-nb-posts">(<a href="' . $core->adminurl->get("admin.posts", ['cat_id' => $rs->cat_id]) . '">' .
|
||||
sprintf(($rs->nb_post > 1 ? __('%d entries') : __('%d entry')), $rs->nb_post) . '</a>' .
|
||||
', ' . __('total:') . ' ' . $rs->nb_total . ')</p>' .
|
||||
'<p class="cat-url">' . __('URL:') . ' <code>' . html::escapeHTML($rs->cat_url) . '</code></p>';
|
||||
|
||||
echo
|
||||
'<p class="cat-buttons">';
|
||||
if ($rs->nb_total > 0) {
|
||||
// remove current category
|
||||
echo
|
||||
'<label for="mov_cat_' . $rs->cat_id . '">' . __('Move entries to') . '</label> ' .
|
||||
form::combo(['mov_cat[' . $rs->cat_id . ']', 'mov_cat_' . $rs->cat_id], array_filter($categories_combo,
|
||||
function ($cat) {return $cat->value != $GLOBALS['rs']->cat_id;}
|
||||
), '', '') .
|
||||
' <input type="submit" class="reset" name="mov[' . $rs->cat_id . ']" value="' . __('OK') . '"/>';
|
||||
|
||||
$attr_disabled = ' disabled="disabled"';
|
||||
$input_class = 'disabled ';
|
||||
} else {
|
||||
$attr_disabled = '';
|
||||
$input_class = '';
|
||||
}
|
||||
echo
|
||||
' <input type="submit"' . $attr_disabled . ' class="' . $input_class . 'delete" name="delete[' . $rs->cat_id . ']" value="' . __('Delete category') . '"/>' .
|
||||
'</p>';
|
||||
|
||||
$level = $rs->level;
|
||||
}
|
||||
|
||||
if ($ref_level - $level < 0) {
|
||||
echo str_repeat('</li></ul>', -($ref_level - $level));
|
||||
}
|
||||
echo
|
||||
'</div>';
|
||||
|
||||
echo '<div class="clear">';
|
||||
|
||||
if ($core->auth->check('categories', $core->blog->id) && $rs->count() > 1) {
|
||||
if (!$core->auth->user_prefs->accessibility->nodragdrop) {
|
||||
echo '<p class="form-note hidden-if-no-js">' . __('To rearrange categories order, move items by drag and drop, then click on “Save categories order” button.') . '</p>';
|
||||
}
|
||||
echo
|
||||
'<p><span class="hidden-if-no-js">' .
|
||||
'<input type="hidden" id="categories_order" name="categories_order" value=""/>' .
|
||||
'<input type="submit" name="save_order" id="save-set-order" value="' . __('Save categories order') . '" />' .
|
||||
'</span> ';
|
||||
} else {
|
||||
echo '<p>';
|
||||
}
|
||||
|
||||
echo
|
||||
'<input type="submit" class="reset" name="reset" value="' . __('Reorder all categories on the top level') . '" />' .
|
||||
$core->formNonce() . '</p>' .
|
||||
'</div></form>';
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
|
||||
dcPage::helpBlock('core_categories');
|
||||
dcPage::close();
|
||||
263
dotclear._no/admin/category.php
Normal file
@ -0,0 +1,263 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*/
|
||||
|
||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
||||
|
||||
dcPage::check('categories');
|
||||
|
||||
$cat_id = '';
|
||||
$cat_title = '';
|
||||
$cat_url = '';
|
||||
$cat_desc = '';
|
||||
$cat_position = '';
|
||||
|
||||
$blog_settings = new dcSettings($core, $core->blog->id);
|
||||
$blog_lang = $blog_settings->system->lang;
|
||||
|
||||
# Getting existing category
|
||||
if (!empty($_REQUEST['id'])) {
|
||||
try {
|
||||
$rs = $core->blog->getCategory($_REQUEST['id']);
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
|
||||
if (!$core->error->flag() && !$rs->isEmpty()) {
|
||||
$cat_id = (integer) $rs->cat_id;
|
||||
$cat_title = $rs->cat_title;
|
||||
$cat_url = $rs->cat_url;
|
||||
$cat_desc = $rs->cat_desc;
|
||||
}
|
||||
unset($rs);
|
||||
|
||||
# Getting hierarchy information
|
||||
$parents = $core->blog->getCategoryParents($cat_id);
|
||||
$rs = $core->blog->getCategoryParent($cat_id);
|
||||
$cat_parent = $rs->isEmpty() ? 0 : (integer) $rs->cat_id;
|
||||
unset($rs);
|
||||
|
||||
# Allowed parents list
|
||||
$children = $core->blog->getCategories(['start' => $cat_id]);
|
||||
$allowed_parents = [__('Top level') => 0];
|
||||
|
||||
$p = [];
|
||||
while ($children->fetch()) {
|
||||
$p[$children->cat_id] = 1;
|
||||
}
|
||||
|
||||
$rs = $core->blog->getCategories();
|
||||
while ($rs->fetch()) {
|
||||
if (!isset($p[$rs->cat_id])) {
|
||||
$allowed_parents[] = new formSelectOption(
|
||||
str_repeat(' ', $rs->level - 1) . ($rs->level - 1 == 0 ? '' : '• ') . html::escapeHTML($rs->cat_title),
|
||||
$rs->cat_id
|
||||
);
|
||||
}
|
||||
}
|
||||
unset($rs);
|
||||
|
||||
# Allowed siblings list
|
||||
$siblings = [];
|
||||
$rs = $core->blog->getCategoryFirstChildren($cat_parent);
|
||||
while ($rs->fetch()) {
|
||||
if ($rs->cat_id != $cat_id) {
|
||||
$siblings[html::escapeHTML($rs->cat_title)] = $rs->cat_id;
|
||||
}
|
||||
}
|
||||
unset($rs);
|
||||
}
|
||||
|
||||
# Changing parent
|
||||
if ($cat_id && isset($_POST['cat_parent'])) {
|
||||
$new_parent = (integer) $_POST['cat_parent'];
|
||||
if ($cat_parent != $new_parent) {
|
||||
try {
|
||||
$core->blog->setCategoryParent($cat_id, $new_parent);
|
||||
dcPage::addSuccessNotice(__('The category has been successfully moved'));
|
||||
$core->adminurl->redirect("admin.categories");
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Changing sibling
|
||||
if ($cat_id && isset($_POST['cat_sibling'])) {
|
||||
try {
|
||||
$core->blog->setCategoryPosition($cat_id, (integer) $_POST['cat_sibling'], $_POST['cat_move']);
|
||||
dcPage::addSuccessNotice(__('The category has been successfully moved'));
|
||||
$core->adminurl->redirect("admin.categories");
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
# Create or update a category
|
||||
if (isset($_POST['cat_title'])) {
|
||||
$cur = $core->con->openCursor($core->prefix . 'category');
|
||||
|
||||
$cur->cat_title = $cat_title = $_POST['cat_title'];
|
||||
|
||||
if (isset($_POST['cat_desc'])) {
|
||||
$cur->cat_desc = $cat_desc = $_POST['cat_desc'];
|
||||
}
|
||||
|
||||
if (isset($_POST['cat_url'])) {
|
||||
$cur->cat_url = $cat_url = $_POST['cat_url'];
|
||||
} else {
|
||||
$cur->cat_url = $cat_url;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
# Update category
|
||||
if ($cat_id) {
|
||||
# --BEHAVIOR-- adminBeforeCategoryUpdate
|
||||
$core->callBehavior('adminBeforeCategoryUpdate', $cur, $cat_id);
|
||||
|
||||
$core->blog->updCategory($_POST['id'], $cur);
|
||||
|
||||
# --BEHAVIOR-- adminAfterCategoryUpdate
|
||||
$core->callBehavior('adminAfterCategoryUpdate', $cur, $cat_id);
|
||||
|
||||
dcPage::addSuccessNotice(__('The category has been successfully updated.'));
|
||||
|
||||
$core->adminurl->redirect("admin.category", ['id' => $_POST['id']]);
|
||||
}
|
||||
# Create category
|
||||
else {
|
||||
# --BEHAVIOR-- adminBeforeCategoryCreate
|
||||
$core->callBehavior('adminBeforeCategoryCreate', $cur);
|
||||
|
||||
$id = $core->blog->addCategory($cur, (integer) $_POST['new_cat_parent']);
|
||||
|
||||
# --BEHAVIOR-- adminAfterCategoryCreate
|
||||
$core->callBehavior('adminAfterCategoryCreate', $cur, $id);
|
||||
|
||||
dcPage::addSuccessNotice(sprintf(__('The category "%s" has been successfully created.'),
|
||||
html::escapeHTML($cur->cat_title)));
|
||||
$core->adminurl->redirect("admin.categories");
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
$title = $cat_id ? html::escapeHTML($cat_title) : __('New category');
|
||||
|
||||
$elements = [
|
||||
html::escapeHTML($core->blog->name) => '',
|
||||
__('Categories') => $core->adminurl->get("admin.categories")
|
||||
];
|
||||
if ($cat_id) {
|
||||
while ($parents->fetch()) {
|
||||
$elements[html::escapeHTML($parents->cat_title)] = $core->adminurl->get("admin.category", ['id' => $parents->cat_id]);
|
||||
}
|
||||
}
|
||||
$elements[$title] = '';
|
||||
|
||||
$category_editor = $core->auth->getOption('editor');
|
||||
$rte_flag = true;
|
||||
$rte_flags = @$core->auth->user_prefs->interface->rte_flags;
|
||||
if (is_array($rte_flags) && in_array('cat_descr', $rte_flags)) {
|
||||
$rte_flag = $rte_flags['cat_descr'];
|
||||
}
|
||||
|
||||
dcPage::open($title,
|
||||
dcPage::jsConfirmClose('category-form') .
|
||||
dcPage::jsLoad('js/_category.js') .
|
||||
($rte_flag ? $core->callBehavior('adminPostEditor', $category_editor['xhtml'], 'category', ['#cat_desc'], 'xhtml') : ''),
|
||||
dcPage::breadcrumb($elements)
|
||||
);
|
||||
|
||||
if (!empty($_GET['upd'])) {
|
||||
dcPage::success(__('Category has been successfully updated.'));
|
||||
}
|
||||
|
||||
echo
|
||||
'<form action="' . $core->adminurl->get("admin.category") . '" method="post" id="category-form">' .
|
||||
'<h3>' . __('Category information') . '</h3>' .
|
||||
'<p><label class="required" for="cat_title"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Name:') . '</label> ' .
|
||||
form::field('cat_title', 40, 255, [
|
||||
'default' => html::escapeHTML($cat_title),
|
||||
'extra_html' => 'required placeholder="' . __('Name') . '" lang="' . $blog_lang . '" spellcheck="true"'
|
||||
]) .
|
||||
'</p>';
|
||||
if (!$cat_id) {
|
||||
$rs = $core->blog->getCategories();
|
||||
echo
|
||||
'<p><label for="new_cat_parent">' . __('Parent:') . ' ' .
|
||||
'<select id="new_cat_parent" name="new_cat_parent" >' .
|
||||
'<option value="0">' . __('(none)') . '</option>';
|
||||
while ($rs->fetch()) {
|
||||
echo '<option value="' . $rs->cat_id . '" ' . (!empty($_POST['new_cat_parent']) && $_POST['new_cat_parent'] == $rs->cat_id ? 'selected="selected"' : '') . '>' .
|
||||
str_repeat(' ', $rs->level - 1) . ($rs->level - 1 == 0 ? '' : '• ') . html::escapeHTML($rs->cat_title) . '</option>';
|
||||
}
|
||||
echo
|
||||
'</select></label></p>';
|
||||
unset($rs);
|
||||
}
|
||||
echo
|
||||
'<div class="lockable">' .
|
||||
'<p><label for="cat_url">' . __('URL:') . '</label> '
|
||||
. form::field('cat_url', 40, 255, html::escapeHTML($cat_url)) .
|
||||
'</p>' .
|
||||
'<p class="form-note warn" id="note-cat-url">' .
|
||||
__('Warning: If you set the URL manually, it may conflict with another category.') . '</p>' .
|
||||
'</div>' .
|
||||
|
||||
'<p class="area"><label for="cat_desc">' . __('Description:') . '</label> ' .
|
||||
form::textarea('cat_desc', 50, 8,
|
||||
[
|
||||
'default' => html::escapeHTML($cat_desc),
|
||||
'extra_html' => 'lang="' . $blog_lang . '" spellcheck="true"'
|
||||
]) .
|
||||
'</p>' .
|
||||
|
||||
'<p><input type="submit" accesskey="s" value="' . __('Save') . '" />' .
|
||||
($cat_id ? form::hidden('id', $cat_id) : '') .
|
||||
$core->formNonce() .
|
||||
'</p>' .
|
||||
'</form>';
|
||||
|
||||
if ($cat_id) {
|
||||
echo
|
||||
'<h3 class="border-top">' . __('Move this category') . '</h3>' .
|
||||
'<div class="two-cols">' .
|
||||
'<div class="col">' .
|
||||
|
||||
'<form action="' . $core->adminurl->get("admin.category") . '" method="post" class="fieldset">' .
|
||||
'<h4>' . __('Category parent') . '</h4>' .
|
||||
'<p><label for="cat_parent" class="classic">' . __('Parent:') . '</label> ' .
|
||||
form::combo('cat_parent', $allowed_parents, $cat_parent) . '</p>' .
|
||||
'<p><input type="submit" accesskey="s" value="' . __('Save') . '" />' .
|
||||
form::hidden(['id'], $cat_id) . $core->formNonce() . '</p>' .
|
||||
'</form>' .
|
||||
'</div>';
|
||||
|
||||
if (count($siblings) > 0) {
|
||||
echo
|
||||
'<div class="col">' .
|
||||
'<form action="' . $core->adminurl->get("admin.category") . '" method="post" class="fieldset">' .
|
||||
'<h4>' . __('Category sibling') . '</h4>' .
|
||||
'<p><label class="classic" for="cat_sibling">' . __('Move current category') . '</label> ' .
|
||||
form::combo('cat_move', [__('before') => 'before', __('after') => 'after'],
|
||||
['extra_html' => 'title="' . __('position: ') . '"']) . ' ' .
|
||||
form::combo('cat_sibling', $siblings) . '</p>' .
|
||||
'<p><input type="submit" accesskey="s" value="' . __('Save') . '" />' .
|
||||
form::hidden(['id'], $cat_id) . $core->formNonce() . '</p>' .
|
||||
'</form>' .
|
||||
'</div>';
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
dcPage::helpBlock('core_category');
|
||||
dcPage::close();
|
||||
252
dotclear._no/admin/comment.php
Normal file
@ -0,0 +1,252 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*/
|
||||
|
||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
||||
|
||||
dcPage::check('usage,contentadmin');
|
||||
|
||||
$comment_id = null;
|
||||
$comment_dt = '';
|
||||
$comment_author = '';
|
||||
$comment_email = '';
|
||||
$comment_site = '';
|
||||
$comment_content = '';
|
||||
$comment_ip = '';
|
||||
$comment_status = '';
|
||||
$comment_trackback = 0;
|
||||
$comment_spam_status = '';
|
||||
|
||||
$comment_editor = $core->auth->getOption('editor');
|
||||
|
||||
# Status combo
|
||||
$status_combo = dcAdminCombos::getCommentStatusescombo();
|
||||
|
||||
# Adding comment (comming from post form, comments tab)
|
||||
if (!empty($_POST['add']) && !empty($_POST['post_id'])) {
|
||||
try
|
||||
{
|
||||
$rs = $core->blog->getPosts(['post_id' => $_POST['post_id'], 'post_type' => '']);
|
||||
|
||||
if ($rs->isEmpty()) {
|
||||
throw new Exception(__('Entry does not exist.'));
|
||||
}
|
||||
|
||||
$cur = $core->con->openCursor($core->prefix . 'comment');
|
||||
|
||||
$cur->comment_author = $_POST['comment_author'];
|
||||
$cur->comment_email = html::clean($_POST['comment_email']);
|
||||
$cur->comment_site = html::clean($_POST['comment_site']);
|
||||
$cur->comment_content = $core->HTMLfilter($_POST['comment_content']);
|
||||
$cur->post_id = (integer) $_POST['post_id'];
|
||||
|
||||
# --BEHAVIOR-- adminBeforeCommentCreate
|
||||
$core->callBehavior('adminBeforeCommentCreate', $cur);
|
||||
|
||||
$comment_id = $core->blog->addComment($cur);
|
||||
|
||||
# --BEHAVIOR-- adminAfterCommentCreate
|
||||
$core->callBehavior('adminAfterCommentCreate', $cur, $comment_id);
|
||||
|
||||
dcPage::addSuccessNotice(__('Comment has been successfully created.'));
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
http::redirect($core->getPostAdminURL($rs->post_type, $rs->post_id, false) . '&co=1');
|
||||
}
|
||||
|
||||
if (!empty($_REQUEST['id'])) {
|
||||
$params['comment_id'] = $_REQUEST['id'];
|
||||
|
||||
try {
|
||||
$rs = $core->blog->getComments($params);
|
||||
if (!$rs->isEmpty()) {
|
||||
$comment_id = $rs->comment_id;
|
||||
$post_id = $rs->post_id;
|
||||
$post_type = $rs->post_type;
|
||||
$post_title = $rs->post_title;
|
||||
$comment_dt = $rs->comment_dt;
|
||||
$comment_author = $rs->comment_author;
|
||||
$comment_email = $rs->comment_email;
|
||||
$comment_site = $rs->comment_site;
|
||||
$comment_content = $rs->comment_content;
|
||||
$comment_ip = $rs->comment_ip;
|
||||
$comment_status = $rs->comment_status;
|
||||
$comment_trackback = (boolean) $rs->comment_trackback;
|
||||
$comment_spam_status = $rs->comment_spam_status;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (!$comment_id && !$core->error->flag()) {
|
||||
$core->error->add(__('No comments'));
|
||||
}
|
||||
|
||||
if (!$core->error->flag() && isset($rs)) {
|
||||
$can_edit = $can_delete = $can_publish = $core->auth->check('contentadmin', $core->blog->id);
|
||||
|
||||
if (!$core->auth->check('contentadmin', $core->blog->id) && $core->auth->userID() == $rs->user_id) {
|
||||
$can_edit = true;
|
||||
if ($core->auth->check('delete', $core->blog->id)) {
|
||||
$can_delete = true;
|
||||
}
|
||||
if ($core->auth->check('publish', $core->blog->id)) {
|
||||
$can_publish = true;
|
||||
}
|
||||
}
|
||||
|
||||
# update comment
|
||||
if (!empty($_POST['update']) && $can_edit) {
|
||||
$cur = $core->con->openCursor($core->prefix . 'comment');
|
||||
|
||||
$cur->comment_author = $_POST['comment_author'];
|
||||
$cur->comment_email = html::clean($_POST['comment_email']);
|
||||
$cur->comment_site = html::clean($_POST['comment_site']);
|
||||
$cur->comment_content = $core->HTMLfilter($_POST['comment_content']);
|
||||
|
||||
if (isset($_POST['comment_status'])) {
|
||||
$cur->comment_status = (integer) $_POST['comment_status'];
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
# --BEHAVIOR-- adminBeforeCommentUpdate
|
||||
$core->callBehavior('adminBeforeCommentUpdate', $cur, $comment_id);
|
||||
|
||||
$core->blog->updComment($comment_id, $cur);
|
||||
|
||||
# --BEHAVIOR-- adminAfterCommentUpdate
|
||||
$core->callBehavior('adminAfterCommentUpdate', $cur, $comment_id);
|
||||
|
||||
dcPage::addSuccessNotice(__('Comment has been successfully updated.'));
|
||||
$core->adminurl->redirect("admin.comment", ['id' => $comment_id]);
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_POST['delete']) && $can_delete) {
|
||||
try {
|
||||
# --BEHAVIOR-- adminBeforeCommentDelete
|
||||
$core->callBehavior('adminBeforeCommentDelete', $comment_id);
|
||||
|
||||
$core->blog->delComment($comment_id);
|
||||
|
||||
dcPage::addSuccessNotice(__('Comment has been successfully deleted.'));
|
||||
http::redirect($core->getPostAdminURL($rs->post_type, $rs->post_id) . '&co=1', false);
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (!$can_edit) {
|
||||
$core->error->add(__("You can't edit this comment."));
|
||||
}
|
||||
}
|
||||
|
||||
/* DISPLAY
|
||||
-------------------------------------------------------- */
|
||||
if ($comment_id) {
|
||||
$breadcrumb = dcPage::breadcrumb(
|
||||
[
|
||||
html::escapeHTML($core->blog->name) => '',
|
||||
html::escapeHTML($post_title) => $core->getPostAdminURL($post_type, $post_id) . '&co=1#c' . $comment_id,
|
||||
__('Edit comment') => ''
|
||||
]);
|
||||
} else {
|
||||
$breadcrumb = dcPage::breadcrumb(
|
||||
[
|
||||
html::escapeHTML($core->blog->name) => '',
|
||||
html::escapeHTML($post_title) => $core->getPostAdminURL($post_type, $post_id),
|
||||
__('Edit comment') => ''
|
||||
]);
|
||||
}
|
||||
|
||||
dcPage::open(__('Edit comment'),
|
||||
dcPage::jsConfirmClose('comment-form') .
|
||||
dcPage::jsLoad('js/_comment.js') .
|
||||
$core->callBehavior('adminPostEditor', $comment_editor['xhtml'], 'comment', ['#comment_content'], 'xhtml') .
|
||||
# --BEHAVIOR-- adminCommentHeaders
|
||||
$core->callBehavior('adminCommentHeaders'),
|
||||
$breadcrumb
|
||||
);
|
||||
|
||||
if ($comment_id) {
|
||||
if (!empty($_GET['upd'])) {
|
||||
dcPage::success(__('Comment has been successfully updated.'));
|
||||
}
|
||||
|
||||
$comment_mailto = '';
|
||||
if ($comment_email) {
|
||||
$comment_mailto = '<a href="mailto:' . html::escapeHTML($comment_email)
|
||||
. '?subject=' . rawurlencode(sprintf(__('Your comment on my blog %s'), $core->blog->name))
|
||||
. '&body='
|
||||
. rawurlencode(sprintf(__("Hi!\n\nYou wrote a comment on:\n%s\n\n\n"), $rs->getPostURL()))
|
||||
. '">' . __('Send an e-mail') . '</a>';
|
||||
}
|
||||
|
||||
echo
|
||||
'<form action="' . $core->adminurl->get("admin.comment") . '" method="post" id="comment-form">' .
|
||||
'<div class="fieldset">' .
|
||||
'<h3>' . __('Information collected') . '</h3>' .
|
||||
'<p>' . __('IP address:') . ' ' .
|
||||
'<a href="' . $core->adminurl->get("admin.comments", ['ip' => $comment_ip]) . '">' . $comment_ip . '</a></p>' .
|
||||
|
||||
'<p>' . __('Date:') . ' ' .
|
||||
dt::dt2str(__('%Y-%m-%d %H:%M'), $comment_dt) . '</p>' .
|
||||
'</div>' .
|
||||
|
||||
'<h3>' . __('Comment submitted') . '</h3>' .
|
||||
'<p><label for="comment_author" class="required"><abbr title="' . __('Required field') . '">*</abbr>' . __('Author:') . '</label>' .
|
||||
form::field('comment_author', 30, 255, [
|
||||
'default' => html::escapeHTML($comment_author),
|
||||
'extra_html' => 'required placeholder="' . __('Author') . '"'
|
||||
]) .
|
||||
'</p>' .
|
||||
|
||||
'<p><label for="comment_email">' . __('Email:') . '</label>' .
|
||||
form::email('comment_email', 30, 255, html::escapeHTML($comment_email)) .
|
||||
'<span>' . $comment_mailto . '</span>' .
|
||||
'</p>' .
|
||||
|
||||
'<p><label for="comment_site">' . __('Web site:') . '</label>' .
|
||||
form::url('comment_site', 30, 255, html::escapeHTML($comment_site)) .
|
||||
'</p>' .
|
||||
|
||||
'<p><label for="comment_status">' . __('Status:') . '</label>' .
|
||||
form::combo('comment_status', $status_combo,
|
||||
['default' => $comment_status, 'disabled' => !$can_publish]) .
|
||||
'</p>' .
|
||||
|
||||
# --BEHAVIOR-- adminAfterCommentDesc
|
||||
$core->callBehavior('adminAfterCommentDesc', $rs) .
|
||||
|
||||
'<p class="area"><label for="comment_content">' . __('Comment:') . '</label> ' .
|
||||
form::textarea('comment_content', 50, 10,
|
||||
[
|
||||
'default' => html::escapeHTML($comment_content),
|
||||
'extra_html' => 'lang="' . $core->auth->getInfo('user_lang') . '" spellcheck="true"'
|
||||
]) .
|
||||
'</p>' .
|
||||
|
||||
'<p>' . form::hidden('id', $comment_id) .
|
||||
$core->formNonce() .
|
||||
'<input type="submit" accesskey="s" name="update" value="' . __('Save') . '" /> ';
|
||||
|
||||
if ($can_delete) {
|
||||
echo '<input type="submit" class="delete" name="delete" value="' . __('Delete') . '" />';
|
||||
}
|
||||
echo
|
||||
'</p>' .
|
||||
'</form>';
|
||||
}
|
||||
|
||||
dcPage::helpBlock('core_comments');
|
||||
dcPage::close();
|
||||
302
dotclear._no/admin/comments.php
Normal file
@ -0,0 +1,302 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*/
|
||||
|
||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
||||
|
||||
dcPage::check('usage,contentadmin');
|
||||
|
||||
if (!empty($_POST['delete_all_spam'])) {
|
||||
try {
|
||||
$core->blog->delJunkComments();
|
||||
$_SESSION['comments_del_spam'] = true;
|
||||
$core->adminurl->redirect("admin.comments");
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
# Creating filter combo boxes
|
||||
# Filter form we'll put in html_block
|
||||
$status_combo = array_merge(
|
||||
['-' => ''],
|
||||
dcAdminCombos::getCommentStatusescombo()
|
||||
);
|
||||
|
||||
$type_combo = [
|
||||
'-' => '',
|
||||
__('Comment') => 'co',
|
||||
__('Trackback') => 'tb'
|
||||
];
|
||||
|
||||
$sortby_combo = [
|
||||
__('Date') => 'comment_dt',
|
||||
__('Entry title') => 'post_title',
|
||||
__('Entry date') => 'post_dt',
|
||||
__('Author') => 'comment_author',
|
||||
__('Status') => 'comment_status'
|
||||
];
|
||||
|
||||
$sortby_lex = [
|
||||
// key in sorty_combo (see above) => field in SQL request
|
||||
'post_title' => 'post_title',
|
||||
'comment_author' => 'comment_author',
|
||||
'comment_spam_filter' => 'comment_spam_filter'];
|
||||
|
||||
$order_combo = [
|
||||
__('Descending') => 'desc',
|
||||
__('Ascending') => 'asc'
|
||||
];
|
||||
|
||||
/* Get comments
|
||||
-------------------------------------------------------- */
|
||||
$author = isset($_GET['author']) ? $_GET['author'] : '';
|
||||
$status = isset($_GET['status']) ? $_GET['status'] : '';
|
||||
$type = !empty($_GET['type']) ? $_GET['type'] : '';
|
||||
$sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'comment_dt';
|
||||
$order = !empty($_GET['order']) ? $_GET['order'] : 'desc';
|
||||
$ip = !empty($_GET['ip']) ? $_GET['ip'] : '';
|
||||
$email = !empty($_GET['email']) ? $_GET['email'] : '';
|
||||
$site = !empty($_GET['site']) ? $_GET['site'] : '';
|
||||
|
||||
$with_spam = $author || $status || $type || $sortby != 'comment_dt' || $order != 'desc' || $ip;
|
||||
|
||||
$show_filters = false;
|
||||
|
||||
$page = !empty($_GET['page']) ? max(1, (integer) $_GET['page']) : 1;
|
||||
$nb_per_page = 30;
|
||||
|
||||
if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) {
|
||||
if ($nb_per_page != (integer) $_GET['nb']) {
|
||||
$show_filters = true;
|
||||
}
|
||||
$nb_per_page = (integer) $_GET['nb'];
|
||||
}
|
||||
|
||||
$params['limit'] = [(($page - 1) * $nb_per_page), $nb_per_page];
|
||||
$params['no_content'] = true;
|
||||
|
||||
# Author filter
|
||||
if ($author !== '') {
|
||||
$params['q_author'] = $author;
|
||||
$show_filters = true;
|
||||
} else {
|
||||
$author = '';
|
||||
}
|
||||
|
||||
# - Type filter
|
||||
if ($type == 'tb' || $type == 'co') {
|
||||
$params['comment_trackback'] = ($type == 'tb');
|
||||
$show_filters = true;
|
||||
} else {
|
||||
$type = '';
|
||||
}
|
||||
|
||||
# - Status filter
|
||||
if ($status !== '' && in_array($status, $status_combo)) {
|
||||
$params['comment_status'] = $status;
|
||||
$show_filters = true;
|
||||
} elseif (!$with_spam) {
|
||||
$params['comment_status_not'] = -2;
|
||||
$status = '';
|
||||
} else {
|
||||
$status = '';
|
||||
}
|
||||
|
||||
# - IP filter
|
||||
if ($ip) {
|
||||
$params['comment_ip'] = $ip;
|
||||
$show_filters = true;
|
||||
}
|
||||
|
||||
# - email filter
|
||||
if ($email) {
|
||||
$params['comment_email'] = $email;
|
||||
$show_filters = true;
|
||||
}
|
||||
|
||||
# - site filter
|
||||
if ($site) {
|
||||
$params['comment_site'] = $site;
|
||||
$show_filters = true;
|
||||
}
|
||||
|
||||
// Add some sort order if spams displayed
|
||||
if ($with_spam || ($status == -2)) {
|
||||
$sortby_combo[__('IP')] = 'comment_ip';
|
||||
$sortby_combo[__('Spam filter')] = 'comment_spam_filter';
|
||||
}
|
||||
|
||||
# Sortby and order filter
|
||||
if ($sortby !== '' && in_array($sortby, $sortby_combo)) {
|
||||
if (array_key_exists($sortby, $sortby_lex)) {
|
||||
$params['order'] = $core->con->lexFields($sortby_lex[$sortby]);
|
||||
} else {
|
||||
$params['order'] = $sortby;
|
||||
}
|
||||
if ($order !== '' && in_array($order, $order_combo)) {
|
||||
$params['order'] .= ' ' . $order;
|
||||
} else {
|
||||
$order = 'desc';
|
||||
}
|
||||
|
||||
if ($sortby != 'comment_dt' || $order != 'desc') {
|
||||
$show_filters = true;
|
||||
}
|
||||
} else {
|
||||
$sortby = 'comment_dt';
|
||||
$order = 'desc';
|
||||
}
|
||||
|
||||
# Actions combo box
|
||||
$combo_action = [];
|
||||
$default = '';
|
||||
if ($core->auth->check('delete,contentadmin', $core->blog->id) && $status == -2) {
|
||||
$default = 'delete';
|
||||
}
|
||||
|
||||
$comments_actions_page = new dcCommentsActionsPage($core, $core->adminurl->get("admin.comments"));
|
||||
|
||||
if ($comments_actions_page->process()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get comments
|
||||
-------------------------------------------------------- */
|
||||
try {
|
||||
$comments = $core->blog->getComments($params);
|
||||
$counter = $core->blog->getComments($params, true);
|
||||
$comment_list = new adminCommentList($core, $comments, $counter->f(0));
|
||||
} catch (Exception $e) {
|
||||
$core->error->add($e->getMessage());
|
||||
}
|
||||
|
||||
/* DISPLAY
|
||||
-------------------------------------------------------- */
|
||||
|
||||
dcPage::open(__('Comments and trackbacks'),
|
||||
dcPage::jsLoad('js/_comments.js') . dcPage::jsFilterControl($show_filters),
|
||||
dcPage::breadcrumb(
|
||||
[
|
||||
html::escapeHTML($core->blog->name) => '',
|
||||
__('Comments and trackbacks') => ''
|
||||
])
|
||||
);
|
||||
if (!empty($_GET['upd'])) {
|
||||
dcPage::success(__('Selected comments have been successfully updated.'));
|
||||
} elseif (!empty($_GET['del'])) {
|
||||
dcPage::success(__('Selected comments have been successfully deleted.'));
|
||||
}
|
||||
|
||||
if (!$core->error->flag()) {
|
||||
if (isset($_SESSION['comments_del_spam'])) {
|
||||
dcPage::message(__('Spam comments have been successfully deleted.'));
|
||||
unset($_SESSION['comments_del_spam']);
|
||||
}
|
||||
|
||||
$spam_count = $core->blog->getComments(['comment_status' => -2], true)->f(0);
|
||||
if ($spam_count > 0) {
|
||||
|
||||
echo
|
||||
'<form action="' . $core->adminurl->get("admin.comments") . '" method="post" class="fieldset">';
|
||||
|
||||
if (!$with_spam || ($status != -2)) {
|
||||
if ($spam_count == 1) {
|
||||
echo '<p>' . sprintf(__('You have one spam comment.'), '<strong>' . $spam_count . '</strong>') . ' ' .
|
||||
'<a href="' . $core->adminurl->get("admin.comments", ['status' => -2]) . '">' . __('Show it.') . '</a></p>';
|
||||
} elseif ($spam_count > 1) {
|
||||
echo '<p>' . sprintf(__('You have %s spam comments.'), '<strong>' . $spam_count . '</strong>') . ' ' .
|
||||
'<a href="' . $core->adminurl->get("admin.comments", ['status' => -2]) . '">' . __('Show them.') . '</a></p>';
|
||||
}
|
||||
}
|
||||
|
||||
echo
|
||||
'<p>' .
|
||||
$core->formNonce() .
|
||||
'<input name="delete_all_spam" class="delete" type="submit" value="' . __('Delete all spams') . '" /></p>';
|
||||
|
||||
# --BEHAVIOR-- adminCommentsSpamForm
|
||||
$core->callBehavior('adminCommentsSpamForm', $core);
|
||||
|
||||
echo '</form>';
|
||||
}
|
||||
|
||||
echo
|
||||
'<form action="' . $core->adminurl->get("admin.comments") . '" method="get" id="filters-form">' .
|
||||
'<h3 class="out-of-screen-if-js">' . __('Show filters and display options') . '</h3>' .
|
||||
|
||||
'<div class="table">' .
|
||||
'<div class="cell">' .
|
||||
'<h4>' . __('Filters') . '</h4>' .
|
||||
'<p><label for="type" class="ib">' . __('Type:') . '</label> ' .
|
||||
form::combo('type', $type_combo, $type) . '</p> ' .
|
||||
'<p><label for="status" class="ib">' . __('Status:') . '</label> ' .
|
||||
form::combo('status', $status_combo, $status) . '</p>' .
|
||||
'</div>' .
|
||||
|
||||
'<div class="cell filters-sibling-cell">' .
|
||||
'<p><label for="author" class="ib">' . __('Author:') . '</label> ' .
|
||||
form::field('author', 20, 255, html::escapeHTML($author)) . '</p>' .
|
||||
'<p><label for="ip" class="ib">' . __('IP address:') . '</label> ' .
|
||||
form::field('ip', 20, 39, html::escapeHTML($ip)) . '</p>' .
|
||||
'<p><label for="email" class="ib">' . __('Email:') . '</label> ' .
|
||||
form::field('email', 20, 255, html::escapeHTML($email)) . '</p>' .
|
||||
'<p><label for="site" class="ib">' . __('Web site:') . '</label> ' .
|
||||
form::field('site', 20, 255, html::escapeHTML($site)) . '</p>' .
|
||||
'</div>' .
|
||||
|
||||
'<div class="cell filters-options">' .
|
||||
'<h4>' . __('Display options') . '</h4>' .
|
||||
'<p><label for="sortby" class="ib">' . __('Order by:') . '</label> ' .
|
||||
form::combo('sortby', $sortby_combo, $sortby) . '</p>' .
|
||||
'<p><label for="order" class="ib">' . __('Sort:') . '</label> ' .
|
||||
form::combo('order', $order_combo, $order) . '</p>' .
|
||||
'<p><span class="label ib">' . __('Show') . '</span> <label for="nb" class="classic">' .
|
||||
form::number('nb', 0, 999, $nb_per_page) . ' ' .
|
||||
__('comments per page') . '</label></p>' .
|
||||
'</div>' .
|
||||
|
||||
'</div>' .
|
||||
'<p><input type="submit" value="' . __('Apply filters and display options') . '" />' .
|
||||
'<br class="clear" /></p>' . //Opera sucks
|
||||
'</form>';
|
||||
|
||||
# Show comments
|
||||
$comment_list->display($page, $nb_per_page,
|
||||
'<form action="' . $core->adminurl->get("admin.comments") . '" method="post" id="form-comments">' .
|
||||
|
||||
'%s' .
|
||||
|
||||
'<div class="two-cols">' .
|
||||
'<p class="col checkboxes-helpers"></p>' .
|
||||
|
||||
'<p class="col right"><label for="action" class="classic">' . __('Selected comments action:') . '</label> ' .
|
||||
form::combo('action', $comments_actions_page->getCombo(),
|
||||
['default' => $default, 'extra_html' => 'title="' . __('Actions') . '"']) .
|
||||
$core->formNonce() .
|
||||
'<input id="do-action" type="submit" value="' . __('ok') . '" /></p>' .
|
||||
form::hidden(['type'], $type) .
|
||||
form::hidden(['sortby'], $sortby) .
|
||||
form::hidden(['order'], $order) .
|
||||
form::hidden(['author'], html::escapeHTML(preg_replace('/%/', '%%', $author))) .
|
||||
form::hidden(['status'], $status) .
|
||||
form::hidden(['ip'], preg_replace('/%/', '%%', $ip)) .
|
||||
form::hidden(['page'], $page) .
|
||||
form::hidden(['nb'], $nb_per_page) .
|
||||
form::hidden(['email'], html::escapeHTML(preg_replace('/%/', '%%', $email))) .
|
||||
form::hidden(['site'], html::escapeHTML(preg_replace('/%/', '%%', $site))) .
|
||||
'</div>' .
|
||||
|
||||
'</form>',
|
||||
$show_filters,
|
||||
($with_spam || ($status == -2))
|
||||
);
|
||||
}
|
||||
|
||||
dcPage::helpBlock('core_comments');
|
||||
dcPage::close();
|
||||
30
dotclear._no/admin/comments_actions.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*
|
||||
* @deprecated It is only used for plugins compatibility
|
||||
*/
|
||||
|
||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
||||
|
||||
dcPage::check('usage,contentadmin');
|
||||
|
||||
if (isset($_REQUEST['redir'])) {
|
||||
$u = explode('?', $_REQUEST['redir']);
|
||||
$uri = $u[0];
|
||||
if (isset($u[1])) {
|
||||
parse_str($u[1], $args);
|
||||
}
|
||||
$args['redir'] = $_REQUEST['redir'];
|
||||
} else {
|
||||
$uri = $core->adminurl->get("admin.comments");
|
||||
$args = [];
|
||||
}
|
||||
|
||||
$comments_actions_page = new dcCommentsActionsPage($core, $uri, $args);
|
||||
$comments_actions_page->setEnableRedirSelection(false);
|
||||
$comments_actions_page->process();
|
||||
106
dotclear._no/admin/csp_report.php
Normal file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*/
|
||||
|
||||
// From: https://github.com/nico3333fr/CSP-useful
|
||||
//
|
||||
// Note: this script requires PHP ≥ 5.4.
|
||||
// Inspired from https://mathiasbynens.be/notes/csp-reports
|
||||
|
||||
// Dareboost wants it? Not a problem.
|
||||
header('X-Content-Type-Options: "nosniff"');
|
||||
|
||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
||||
|
||||
// Specify admin CSP log file if necessary
|
||||
if (!defined('LOGFILE')) {
|
||||
define('LOGFILE', path::real(DC_VAR) . '/csp/csp_report.json');
|
||||
}
|
||||
|
||||
// Get the raw POST data
|
||||
$data = file_get_contents('php://input');
|
||||
|
||||
// Only continue if it’s valid JSON that is not just `null`, `0`, `false` or an
|
||||
// empty string, i.e. if it could be a CSP violation report.
|
||||
if ($data = json_decode($data, true)) {
|
||||
|
||||
// get source-file and blocked-URI to perform some tests
|
||||
$source_file = isset($data['csp-report']['source-file']) ? $data['csp-report']['source-file'] : '';
|
||||
$line_number = isset($data['csp-report']['line-number']) ? $data['csp-report']['line-number'] : '';
|
||||
$blocked_uri = isset($data['csp-report']['blocked-uri']) ? $data['csp-report']['blocked-uri'] : '';
|
||||
$document_uri = isset($data['csp-report']['document-uri']) ? $data['csp-report']['document-uri'] : '';
|
||||
$violated_directive = isset($data['csp-report']['violated-directive']) ? $data['csp-report']['violated-directive'] : '';
|
||||
|
||||
if (
|
||||
// avoid false positives notifications coming from Chrome extensions (Wappalyzer, MuteTab, etc.)
|
||||
// bug here https://code.google.com/p/chromium/issues/detail?id=524356
|
||||
strpos($source_file, 'chrome-extension://') === false
|
||||
|
||||
// avoid false positives notifications coming from Safari extensions (diigo, evernote, etc.)
|
||||
&& strpos($source_file, 'safari-extension://') === false
|
||||
&& strpos($blocked_uri, 'safari-extension://') === false
|
||||
|
||||
// search engine extensions ?
|
||||
&& strpos($source_file, 'se-extension://') === false
|
||||
|
||||
// added by browsers in webviews
|
||||
&& strpos($blocked_uri, 'webviewprogressproxy://') === false
|
||||
|
||||
// Google Search App see for details https://github.com/nico3333fr/CSP-useful/commit/ecc8f9b0b379ae643bc754d2db33c8b47e185fd1
|
||||
&& strpos($blocked_uri, 'gsa://onpageload') === false
|
||||
|
||||
) {
|
||||
// Prepare report data (hash => info)
|
||||
$hash = hash('md5', $blocked_uri . $document_uri . $source_file . $line_number . $violated_directive);
|
||||
|
||||
try {
|
||||
// Check report dir (create it if necessary)
|
||||
files::makeDir(dirname(LOGFILE), true);
|
||||
|
||||
// Check if report is not already stored in log file
|
||||
$contents = '';
|
||||
if (file_exists(LOGFILE)) {
|
||||
$contents = file_get_contents(LOGFILE);
|
||||
if ($contents && $contents != '') {
|
||||
if (substr($contents, -1) == ',') {
|
||||
// Remove final comma if present
|
||||
$contents = substr($contents, 0, -1);
|
||||
}
|
||||
if ($contents != '') {
|
||||
$list = json_decode('[' . $contents . ']', true);
|
||||
if (is_array($list)) {
|
||||
foreach ($list as $idx => $value) {
|
||||
if (isset($value['hash']) && $value['hash'] == $hash) {
|
||||
// Already stored, ignore
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add report to the file
|
||||
if (!($fp = @fopen(LOGFILE, 'a'))) {
|
||||
// Unable to open file, ignore
|
||||
return;
|
||||
}
|
||||
|
||||
// Prettify the JSON-formatted data
|
||||
$violation = array_merge(['hash' => $hash], $data['csp-report']);
|
||||
$output = json_encode($violation, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
// The file content will have to be enclosed in brackets [] before
|
||||
// beeing decoded with json_decoded(<content>,true);
|
||||
fprintf($fp, ($contents != '' ? ',' : '') . '%s', $output);
|
||||
|
||||
} catch (Exception $e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
34
dotclear._no/admin/dispatcher.php
Executable file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
# -- BEGIN LICENSE BLOCK ---------------------------------------
|
||||
#
|
||||
# This file is part of Dotclear 2.
|
||||
#
|
||||
# Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear
|
||||
# Licensed under the GPL version 2.0 license.
|
||||
# See LICENSE file or
|
||||
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
#
|
||||
# -- END LICENSE BLOCK -----------------------------------------
|
||||
|
||||
# Delete users
|
||||
if (!empty($_REQUEST['dispatch_action']))
|
||||
{
|
||||
if ($_REQUEST['dispatch_action'] == 'deleteuser')
|
||||
{
|
||||
if (!empty($_REQUEST['user_id'])) {
|
||||
$delete_users = $_REQUEST['user_id'];
|
||||
}
|
||||
|
||||
include dirname(__FILE__).'/users.php';
|
||||
exit;
|
||||
}
|
||||
elseif ($_REQUEST['dispatch_action'] == 'setpermissions')
|
||||
{
|
||||
include dirname(__FILE__).'/permissions_blog.php';
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
echo '<p>What the hell are you doing here?</p>';
|
||||
exit;
|
||||
?>
|
||||
95
dotclear._no/admin/help.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*/
|
||||
|
||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
||||
|
||||
dcPage::check('usage,contentadmin');
|
||||
|
||||
$helpPage = function (...$args) {
|
||||
$ret = ['content' => '', 'title' => ''];
|
||||
|
||||
if (empty($args)) {
|
||||
return $ret;
|
||||
}
|
||||
;
|
||||
|
||||
global $__resources;
|
||||
if (empty($__resources['help'])) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$content = '';
|
||||
$title = '';
|
||||
foreach ($args as $v) {
|
||||
if (is_object($v) && isset($v->content)) {
|
||||
$content .= $v->content;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($__resources['help'][$v])) {
|
||||
continue;
|
||||
}
|
||||
$f = $__resources['help'][$v];
|
||||
if (!file_exists($f) || !is_readable($f)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fc = file_get_contents($f);
|
||||
if (preg_match('|<body[^>]*?>(.*?)</body>|ms', $fc, $matches)) {
|
||||
$content .= $matches[1];
|
||||
if (preg_match('|<title[^>]*?>(.*?)</title>|ms', $fc, $matches)) {
|
||||
$title = $matches[1];
|
||||
}
|
||||
} else {
|
||||
$content .= $fc;
|
||||
}
|
||||
}
|
||||
|
||||
if (trim($content) == '') {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$ret['content'] = $content;
|
||||
if ($title != '') {
|
||||
$ret['title'] = $title;
|
||||
}
|
||||
return $ret;
|
||||
};
|
||||
|
||||
$help_page = !empty($_GET['page']) ? html::escapeHTML($_GET['page']) : 'index';
|
||||
$content_array = $helpPage($help_page);
|
||||
if (($content_array['content'] == '') || ($help_page == 'index')) {
|
||||
$content_array = $helpPage('index');
|
||||
}
|
||||
if ($content_array['title'] != '') {
|
||||
$breadcrumb = dcPage::breadcrumb(
|
||||
[
|
||||
__('Global help') => $core->adminurl->get("admin.help"),
|
||||
$content_array['title'] => ''
|
||||
]);
|
||||
} else {
|
||||
$breadcrumb = dcPage::breadcrumb(
|
||||
[
|
||||
__('Global help') => ''
|
||||
]);
|
||||
}
|
||||
|
||||
/* DISPLAY
|
||||
-------------------------------------------------------- */
|
||||
dcPage::open(__('Global help'),
|
||||
dcPage::jsPageTabs('first-step'),
|
||||
$breadcrumb
|
||||
);
|
||||
|
||||
echo $content_array['content'];
|
||||
|
||||
// Prevents global help link display
|
||||
$GLOBALS['__resources']['ctxhelp'] = true;
|
||||
|
||||
dcPage::close();
|
||||
BIN
dotclear._no/admin/images/add.png
Executable file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
dotclear._no/admin/images/admin.png
Normal file
|
After Width: | Height: | Size: 257 B |
BIN
dotclear._no/admin/images/attach.png
Normal file
|
After Width: | Height: | Size: 146 B |
1
dotclear._no/admin/images/attach.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><title>attachment</title><path d="M9.5 19.75a4.25 4.25 0 0 1-4.25-4.25v-6.5a2.75 2.75 0 0 1 5.5 0v6h-1.5v-6a1.25 1.25 0 0 0-2.5 0v6.5a2.75 2.75 0 0 0 5.5 0v-11.5a2.25 2.25 0 0 0-4.5 0v1h-1.5v-1a3.75 3.75 0 0 1 7.5 0v11.5a4.25 4.25 0 0 1-4.25 4.25z" fill="#ff0000"/></svg>
|
||||
|
After Width: | Height: | Size: 332 B |
BIN
dotclear._no/admin/images/check-off.png
Normal file
|
After Width: | Height: | Size: 109 B |
BIN
dotclear._no/admin/images/check-on.png
Normal file
|
After Width: | Height: | Size: 166 B |
BIN
dotclear._no/admin/images/check-wrn.png
Normal file
|
After Width: | Height: | Size: 90 B |
BIN
dotclear._no/admin/images/close.png
Executable file
|
After Width: | Height: | Size: 586 B |
BIN
dotclear._no/admin/images/collapser-hide.png
Normal file
|
After Width: | Height: | Size: 149 B |
BIN
dotclear._no/admin/images/collapser-show.png
Normal file
|
After Width: | Height: | Size: 152 B |
BIN
dotclear._no/admin/images/comments.png
Normal file
|
After Width: | Height: | Size: 226 B |
BIN
dotclear._no/admin/images/date-picker.png
Normal file
|
After Width: | Height: | Size: 601 B |
BIN
dotclear._no/admin/images/disabled_down.png
Normal file
|
After Width: | Height: | Size: 153 B |
BIN
dotclear._no/admin/images/disabled_up.png
Normal file
|
After Width: | Height: | Size: 150 B |
BIN
dotclear._no/admin/images/dotclear_pw.png
Normal file
|
After Width: | Height: | Size: 419 B |
BIN
dotclear._no/admin/images/down.png
Normal file
|
After Width: | Height: | Size: 152 B |
11
dotclear._no/admin/images/dragndrop.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<svg
|
||||
id="mask"
|
||||
viewbox="0 0 16 16"
|
||||
preserveAspectRatio="xMinYMin meet"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<path d="M7.9 7.9l2.1 7.5 1.7-2.6 3.2 3.2 1.1-1.1-3.3-3.2 2.7-1.6z">
|
||||
</path>
|
||||
<path d="M8 12h-7v-9h12v5.4l1 0.2v-6.6h-14v11h8.2z">
|
||||
</path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 313 B |
BIN
dotclear._no/admin/images/edit-mini.png
Normal file
|
After Width: | Height: | Size: 176 B |
BIN
dotclear._no/admin/images/expand.png
Normal file
|
After Width: | Height: | Size: 162 B |
BIN
dotclear._no/admin/images/fav-off.png
Normal file
|
After Width: | Height: | Size: 296 B |
BIN
dotclear._no/admin/images/fav-on.png
Normal file
|
After Width: | Height: | Size: 246 B |
BIN
dotclear._no/admin/images/favicon.ico
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
dotclear._no/admin/images/favicon.png
Executable file
|
After Width: | Height: | Size: 858 B |
BIN
dotclear._no/admin/images/favicon96-login.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
dotclear._no/admin/images/favicon96-logout.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
dotclear._no/admin/images/grid-off.png
Executable file
|
After Width: | Height: | Size: 193 B |
BIN
dotclear._no/admin/images/grid-on.png
Executable file
|
After Width: | Height: | Size: 350 B |
BIN
dotclear._no/admin/images/help.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
dotclear._no/admin/images/hidden.png
Normal file
|
After Width: | Height: | Size: 103 B |
BIN
dotclear._no/admin/images/hide.png
Normal file
|
After Width: | Height: | Size: 139 B |
BIN
dotclear._no/admin/images/junk.png
Normal file
|
After Width: | Height: | Size: 220 B |
BIN
dotclear._no/admin/images/list-off.png
Executable file
|
After Width: | Height: | Size: 210 B |
BIN
dotclear._no/admin/images/list-on.png
Executable file
|
After Width: | Height: | Size: 510 B |
BIN
dotclear._no/admin/images/locker.png
Normal file
|
After Width: | Height: | Size: 182 B |
BIN
dotclear._no/admin/images/logout.png
Normal file
|
After Width: | Height: | Size: 661 B |
BIN
dotclear._no/admin/images/media/audio.png
Normal file
|
After Width: | Height: | Size: 369 B |
BIN
dotclear._no/admin/images/media/blank.png
Normal file
|
After Width: | Height: | Size: 159 B |
BIN
dotclear._no/admin/images/media/document.png
Normal file
|
After Width: | Height: | Size: 240 B |
BIN
dotclear._no/admin/images/media/executable.png
Normal file
|
After Width: | Height: | Size: 404 B |
BIN
dotclear._no/admin/images/media/folder-up.png
Normal file
|
After Width: | Height: | Size: 302 B |
BIN
dotclear._no/admin/images/media/folder.png
Normal file
|
After Width: | Height: | Size: 194 B |
BIN
dotclear._no/admin/images/media/html.png
Normal file
|
After Width: | Height: | Size: 514 B |
BIN
dotclear._no/admin/images/media/image.png
Normal file
|
After Width: | Height: | Size: 366 B |
BIN
dotclear._no/admin/images/media/package.png
Normal file
|
After Width: | Height: | Size: 247 B |
BIN
dotclear._no/admin/images/media/presentation.png
Normal file
|
After Width: | Height: | Size: 439 B |
BIN
dotclear._no/admin/images/media/spreadsheet.png
Normal file
|
After Width: | Height: | Size: 343 B |
BIN
dotclear._no/admin/images/media/text.png
Normal file
|
After Width: | Height: | Size: 326 B |
BIN
dotclear._no/admin/images/media/video.png
Normal file
|
After Width: | Height: | Size: 298 B |
BIN
dotclear._no/admin/images/menu/add_to_favorites.png
Executable file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
dotclear._no/admin/images/menu/blog-pref-b.png
Normal file
|
After Width: | Height: | Size: 511 B |
BIN
dotclear._no/admin/images/menu/blog-pref.png
Normal file
|
After Width: | Height: | Size: 232 B |
BIN
dotclear._no/admin/images/menu/blog-theme-b-update.png
Normal file
|
After Width: | Height: | Size: 730 B |
BIN
dotclear._no/admin/images/menu/blog-theme-b.png
Normal file
|
After Width: | Height: | Size: 467 B |
BIN
dotclear._no/admin/images/menu/blogs-b.png
Normal file
|
After Width: | Height: | Size: 203 B |
BIN
dotclear._no/admin/images/menu/blogs.png
Normal file
|
After Width: | Height: | Size: 142 B |
BIN
dotclear._no/admin/images/menu/categories-b.png
Normal file
|
After Width: | Height: | Size: 448 B |
BIN
dotclear._no/admin/images/menu/categories.png
Normal file
|
After Width: | Height: | Size: 220 B |
BIN
dotclear._no/admin/images/menu/comments-b.png
Normal file
|
After Width: | Height: | Size: 820 B |
BIN
dotclear._no/admin/images/menu/comments.png
Normal file
|
After Width: | Height: | Size: 283 B |
BIN
dotclear._no/admin/images/menu/dashboard.png
Executable file
|
After Width: | Height: | Size: 256 B |
BIN
dotclear._no/admin/images/menu/edit-b.png
Normal file
|
After Width: | Height: | Size: 469 B |