commit a096ce07cf5e22912f2b1eb01dff179dc2c3aae4 Author: Charlie Root Date: Mon Mar 20 12:18:38 2023 +0100 Current oav website diff --git a/.tmp/Archive.zip b/.tmp/Archive.zip new file mode 100644 index 0000000..307eb6f Binary files /dev/null and b/.tmp/Archive.zip differ diff --git a/.tmp/index.html b/.tmp/index.html new file mode 100644 index 0000000..77cab40 --- /dev/null +++ b/.tmp/index.html @@ -0,0 +1 @@ +Beuuuuuaaaaa diff --git a/_blank.gif b/_blank.gif new file mode 100644 index 0000000..da3a7a1 Binary files /dev/null and b/_blank.gif differ diff --git a/blog/index.php b/blog/index.php new file mode 100644 index 0000000..90a413f --- /dev/null +++ b/blog/index.php @@ -0,0 +1,3 @@ + diff --git a/css/base.css b/css/base.css new file mode 100644 index 0000000..2570e19 --- /dev/null +++ b/css/base.css @@ -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; +} + diff --git a/cv/Xavier_Beaudouin_2005.doc b/cv/Xavier_Beaudouin_2005.doc new file mode 100644 index 0000000..f8c0872 Binary files /dev/null and b/cv/Xavier_Beaudouin_2005.doc differ diff --git a/cv/Xavier_Beaudouin_2005.pdf b/cv/Xavier_Beaudouin_2005.pdf new file mode 100644 index 0000000..a1e3afb Binary files /dev/null and b/cv/Xavier_Beaudouin_2005.pdf differ diff --git a/cv/Xavier_Beaudouin_2006.doc b/cv/Xavier_Beaudouin_2006.doc new file mode 100644 index 0000000..b404739 Binary files /dev/null and b/cv/Xavier_Beaudouin_2006.doc differ diff --git a/cv/Xavier_Beaudouin_2006.pdf b/cv/Xavier_Beaudouin_2006.pdf new file mode 100644 index 0000000..2b28ae9 Binary files /dev/null and b/cv/Xavier_Beaudouin_2006.pdf differ diff --git a/cv/Xavier_Beaudouin_2008.odt b/cv/Xavier_Beaudouin_2008.odt new file mode 100644 index 0000000..2893cff Binary files /dev/null and b/cv/Xavier_Beaudouin_2008.odt differ diff --git a/cv/Xavier_Beaudouin_2008.pdf b/cv/Xavier_Beaudouin_2008.pdf new file mode 100644 index 0000000..d38c7d8 Binary files /dev/null and b/cv/Xavier_Beaudouin_2008.pdf differ diff --git a/cv/Xavier_Beaudouin_2011.docx b/cv/Xavier_Beaudouin_2011.docx new file mode 100644 index 0000000..abeca30 Binary files /dev/null and b/cv/Xavier_Beaudouin_2011.docx differ diff --git a/cv/Xavier_Beaudouin_2011.pdf b/cv/Xavier_Beaudouin_2011.pdf new file mode 100644 index 0000000..7af9419 Binary files /dev/null and b/cv/Xavier_Beaudouin_2011.pdf differ diff --git a/cv/Xavier_Beaudouin_2011_EN_2.pdf b/cv/Xavier_Beaudouin_2011_EN_2.pdf new file mode 100644 index 0000000..a8694a0 Binary files /dev/null and b/cv/Xavier_Beaudouin_2011_EN_2.pdf differ diff --git a/cv/Xavier_Beaudouin_2012.pdf b/cv/Xavier_Beaudouin_2012.pdf new file mode 100644 index 0000000..4366c9e Binary files /dev/null and b/cv/Xavier_Beaudouin_2012.pdf differ diff --git a/cv/Xavier_Beaudouin_2013.pdf b/cv/Xavier_Beaudouin_2013.pdf new file mode 100644 index 0000000..ca83bff Binary files /dev/null and b/cv/Xavier_Beaudouin_2013.pdf differ diff --git a/cv/index.php b/cv/index.php new file mode 100644 index 0000000..1ec750d --- /dev/null +++ b/cv/index.php @@ -0,0 +1,15 @@ + + +

CV / Resume

+

+Here is my CV or Resume. Currently working in Luxembourg at Hotcity SA. +

+

+ diff --git a/cv/xb-motivation.doc b/cv/xb-motivation.doc new file mode 100644 index 0000000..340569c Binary files /dev/null and b/cv/xb-motivation.doc differ diff --git a/cv/xbeaudouin.pdf b/cv/xbeaudouin.pdf new file mode 100644 index 0000000..49ae0b7 Binary files /dev/null and b/cv/xbeaudouin.pdf differ diff --git a/dotclear._no/CHANGELOG b/dotclear._no/CHANGELOG new file mode 100644 index 0000000..3128a12 --- /dev/null +++ b/dotclear._no/CHANGELOG @@ -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 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 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 (= , : ) +* Add 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 /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\ 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 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 ") " 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 +* now works +* 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: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: 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 . +* 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 diff --git a/dotclear._no/CONTRIBUTING.md b/dotclear._no/CONTRIBUTING.md new file mode 100644 index 0000000..792d765 --- /dev/null +++ b/dotclear._no/CONTRIBUTING.md @@ -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) diff --git a/dotclear._no/CREDITS b/dotclear._no/CREDITS new file mode 100644 index 0000000..03cf13d --- /dev/null +++ b/dotclear._no/CREDITS @@ -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. diff --git a/dotclear._no/LICENSE b/dotclear._no/LICENSE new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/dotclear._no/LICENSE @@ -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. + + + Copyright (C) + + 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. + + , 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. diff --git a/dotclear._no/README.md b/dotclear._no/README.md new file mode 100644 index 0000000..6265d3e --- /dev/null +++ b/dotclear._no/README.md @@ -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 diff --git a/dotclear._no/admin/_charte.php b/dotclear._no/admin/_charte.php new file mode 100644 index 0000000..bf81cac --- /dev/null +++ b/dotclear._no/admin/_charte.php @@ -0,0 +1,601 @@ +auth->user_prefs->addWorkspace('interface'); +?> + + + + + + + + Bibliothèque de styles - Dotclear - 2.7 + +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); +?> + + + + + + + + + + + + + + + +
+
+
+
+

Typographie

+

Textes

+

La font-size de base est à 1.2rem (la valeur 1rem correspond à 10px). Si vous utilisez l'unité rem 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.

+

La liste suivante est de class "nice". Elle est semblable aux listes ordinaires mais avec des puces carrées.

+
    +
  • Les textes courants sont en Arial, Helvetica ou sans-serif.
  • +
  • Le code adopte la fonte Andale Mono, Courier New ou monospace.
  • +
  • Les liens ont des aspects différents au focus et au survol. Il faut conserver cette distinction, nécessaire à l'accessibilité et l'ergonomie.
  • +
+ +

Titre h3

+

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.

+

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 "as_h3".

+

Titre de niveau h4

+

On peut obtenir visuellement l'aspect d'un titre h4 en donnant à l'élément la class "as_h4".

+
Titre de niveau h5
+

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.

+
+

Titres des encadrés

+

Les titres de boîte encadrées (div de class "fieldset", comme ici) se présentent comme ci-dessus.

+

On peut utiliser, quel que soit le niveau hx de cet intertitre la class "pretty-title" pour obtenir l'effet ci-dessus.

+
+

Autre variante

+

On dispose également d'une class "smart-title" pour obtenir une présentation comme celle du titre de ce paragraphe.

+ +

Layouts

+ +

Onglets

+

Les descriptions des constructions en multi-colonnes ci-dessous présentent un exemple de répartition en onglets.

+

Chacun de ces onglets doit être défini à l'aide d'une <div class="multi-part">. Ils seront alors automatiquement présentés sous forme d'onglets.

+ +

Multi-colonnage

+
+

Boîtes distribuées horizontalement

+
+
+

1 Toutes les boîtes de class "box" placées à l'intérieur d'une boîte de class "one-box" 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.

+
+
+

2 Voici une petite boîte.

+
+
+

3 Une autre petite boîte.

+
+
+

4 Par défaut les « lignes » de boîtes "box" sont justifiées au sein de la boîte "one-box" et l'espacement se répartit entre elles.

+
+
+

5 Si vous souhaitez un autre alignement des boîtes entre elles vous pouvez ajouter les class :

+
    +
  • "txt-left",
  • +
  • "txt-right"
  • +
  • ou "txt-center"
  • +
+

à la class "one-box".

+
+
+

6 Le cadre placé ici autour de chaque boîte ne fait pas partie des styles par défaut.

+
+
+
+
+

Boîtes distribuées deux par deux

+
+
+

1 Les boîtes de class "two-boxes" ont une règle CSS display:inline-block;. Elles se rangent alternativement à gauche et à droite. Pour plus de clarté, les blocs sont ici numérotés avec leur ordre dans le flux.

+
+

2 On peut assortir une boîte des class "odd" (nothing left) et "even" pour que les marges se placent correctement.

+
+

3 Attention, il faut soit ne pas retourner à la ligne entre la fermeture d'une boîte "two-boxes" et l'ouverture de la suivante soit adopter la méthode de commentaire vide mise en place ici et expliquée chez Alsacréations (« Méthode 2 »).

+
+
+

4 On peut bien sûr imbriquer des boîtes de class "two-boxes" + au sein d'une boîte "two-boxes" afin qu'elles…

+
+

4 bis… se distribuent horizontalement comme dans une boîte "one-box".

+
+
+
+
+
+

Boîtes distribuées trois par trois

+
+
+
+

Sur le même principe que les « two-boxes » on peut utiliser des boîtes de class "three-boxes" pour répartir les contenus sur trois colonnes de 30% chacune (le reste est occupé par les marges).

+
+
+
+

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.

+
+
+
+

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.

+
+
+
+
+
+

Deux colonnes flottantes de largeurs égales

+
+
+

La div englobante porte la class "two-cols", chacune de ses div porte la class "col". + Sans autre précision les deux colonnes sont d'égale largeur.

+
+
+

Attention : ces colonnes sont construites avec des flottants, il faut donc penser à mettre une class clear à l'élément suivant ou ajouter la class "clearfix" à la div class="two-cols".

+
+
+
+
+

Deux colonnes flottantes de largeurs inégales

+
+
+

col70 La div englobante porte la class "two-cols". + Pour obtenir des colonnes inégales, on dispose des classes "col70" et col30 à attribuer à l'une ou à l'autre de ses colonnes.

+
+
+

col30 Penser à mettre une class "clear" à l'élément suivant ou ajouter la class "clearfix" div class="two-cols".

+
+
+
+
+

Trois colonnes flottantes de largeurs égales

+

Deprecated. 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 three-boxes.

+
+
+
Colonne 1
+

La div englobante porte la class "three-cols", chacune de ses div porte la class "col". Les trois colonnes sont d'égale largeur.

+
+
+
Colonne 2
+

Voici une deuxième colonne. N'oubliez pas d'ajouter la class "clearfix" à la class "three-cols" ou un élément de class "clear" après cet élément.

+
+
+
Colonne 3
+

Voilà la troisième colonne.

+
+
+
+
+

Note : dans les exemples les valeurs et les numérotations sont placées dans un span class="step" (et ressortent donc dans un petit bloc à fond gris).

+ +

Interactions

+ +

Éléments de formulaire

+
+
+

+

p class="form-note".

+

+

span class="form-note"

+

+

La class="bold" est bien sûr à écrire en minuscules.

+

+
+
+

+

+ +

+

+

+

+

Les checkboxes et les boutons radio sont dans la balise <label>.

+

+
+
+
+
+ Légende de fieldset +

Attention: Les fieldsets ne doivent être utilisés que pour isoler un groupe de champs au sein d'un formulaire.

+
+
+ +

Boutons

+
+

a.button.add Se place en haut à droite (dans un p.top-add)

+

a.button a.reset

+

a.button delete

+

+
+ +

Messages

+

Messages système

+

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.

+
+

Message simple. Le plus souvent horodaté dcPage::message

+
+
+

Message de succès. Le plus souvent horodaté dcPage::success

+
+
+

Message warning. Non horodaté dcPage::warning

+
+
+

Message d'erreur. Non horodaté dcPage::error

+
+

La classe .static-msg peut être utilisée directement pour affichage en haut de page :

+
+

Comme le message simple mais sans effets de transition.

+
+

Un type de message réservé à Dotclear peut s'afficher en haut de la page :

+ +

Messages contextuels

+

Paragraphe de message d'alerte class warn ou warning.

+

Paragraphe de message de class info.

+

Ces messages sont en display:inline-block. Le fond s'adapte à la longueur du message.

+ +

Navigation

+ +

Selecteur d'accès direct

+

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.

+

+ + + + +

+

Navigation contextuelle

+

Lien vers le blog

+ + +

Pseudo-onglets

+

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.

+

Les pseudo-onglets sont à positionner immédiatement après le breadcrumb (ici un hr simule le trait sous le breadcrumb).

+

Ces pseudo-onglets doivent être définis avec un <ul class="pseudo-tabs"> et des <li>.

+
+ + +

Tableaux

+

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.

+ +

Règles communes

+

Largeur du tableau

+

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 div class="table-outer", + qui servira de « conteneur ».

+

Accessibilité

+

Les éléments caption, th, scope sont nécessaires à l'accessibilité. Ne les oubliez pas ! ». + On peut utiliser la class="hidden" sur l'élément caption (qui accueille + le titre du tableau) si vous ne souhaitez pas qu'il soit affiché sur la page.

+

Les classes

+

Des classes particulières peuvent être attribuées aux lignes :

+
    +
  • line (systématique) : pour les traits horizontaux et le fond gris léger + au survol ;
  • +
  • offline : pour un noir estompé (gris quoi).
  • +
+

Des classes particulières peuvent être appliquées aux cellules :

+
    +
  • nowrap : pas de retour à la ligne dans la cellule, quelle que soit la + largeur de la page ;
  • +
  • maximal : la cellule prendra toute la largeur restante disponible ;
  • +
  • count : le contenu de la cellule sera aligné à droite avec un petit retrait.
  • +
+

Tableau classique

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TitreDateCatégorieAuteurCommentairesRétroliensÉtat
Mon cher Franck06/08/2013 19:16Les aventures du clafoutiskozlika40Publié Sélectionné
Dotclear 2.3.016/05/2011 22:29Les aventures du clafoutiskozlika50Non publié Sélectionné
Causons opéra au Tamm Bara24/11/2009 23:10Les aventures du clafoutiskozlika41Publié
Souffler six bougies14/08/2009 00:00Les aventures du clafoutiskozlika42Publié
Dotclear et grenadine, troisième édition15/06/2009 07:39Les aventures du clafoutiskozlika91Publié
L'abc dotclear est né19/03/2009 10:31Les aventures du clafoutiskozlika10Publié
+
+ +

Tableau avec ordonnancement

+

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).

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TitreDateAuteurCommentairesRétroliensÉtat
+ + + + Mentions légales + 17/12/2008 07:35franck00 + Publié +
+ + + + Page active et cachée + 26/10/2012 11:08admin00 + Publié + Masqué +
+ + + + Page révisionnable + 14/12/2012 13:26admin00 + En attente +
+ + + + Programme + 26/10/2020 11:23admin00 + Programmé +
+ + + + Protégée + 26/10/2012 11:23admin00 + En attente + Protégé +
+
+ +

Icônes

+

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.

+

La plupart sont dérivées de la fonte d'icônes Elegant Font. Les autres sont des images vectorielles réalisées + par la DC Team. Nous les avons nommées Traviata. La palette de couleurs utilisée est la suivante :

+

palette des couleurs utilisées pour les icônes

+

Bleu : #137bbb - Vert : #9ac123 - Rouge : #c44d58 - Bleu ciel : #a2cbe9 - Gris clair : #ececec - + Gris moyen : #b2b2b2 - Gris foncé : #676e78.

+
+
+ + + + +
+ + diff --git a/dotclear._no/admin/auth.php b/dotclear._no/admin/auth.php new file mode 100644 index 0000000..ddd0fae --- /dev/null +++ b/dotclear._no/admin/auth.php @@ -0,0 +1,410 @@ +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.') . ''; + } + } 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+ + +?> + + + + + + + + + + + <?php echo html::escapeHTML(DC_VENDOR_NAME); ?> + + + + + + + + +callBehavior('loginPageHTMLHead'); + +echo dcPage::jsLoad('js/_auth.js'); +?> + + + + +
+

+ +' . $err . ''; +} +if ($msg) { + echo ''; +} + +if ($akey) { + echo '

' . __('Back to login screen') . '

'; +} elseif ($recover) { + echo + '

' . __('Request a new password') . '

' . + '

' . + form::field('user_id', 20, 32, + [ + 'default' => html::escapeHTML($user_id), + 'autocomplete' => 'username' + ] + ) . + '

' . + + '

' . + form::email('user_email', + [ + 'default' => html::escapeHTML($user_email), + 'autocomplete' => 'email' + ] + ) . + '

' . + + '

' . + form::hidden('recover', 1) . '

' . + '
' . + + ''; +} elseif ($change_pwd) { + echo + '

' . __('Change your password') . '

' . + '

' . + form::password('new_pwd', 20, 255, + [ + 'autocomplete' => 'new-password' + ] + ) . '

' . + + '

' . + form::password('new_pwd_c', 20, 255, + [ + 'autocomplete' => 'new-password' + ] + ) . '

' . + '
' . + + '

' . + form::hidden('login_data', $login_data) . '

'; +} else { + if (is_callable([$core->auth, 'authForm'])) { + echo $core->auth->authForm($user_id); + } else { + if ($safe_mode) { + echo '
'; + echo '

' . __('Safe mode login') . '

'; + echo + '

' . + __('This mode allows you to login without activating any of your plugins. This may be useful to solve compatibility problems') . ' 

' . + '

' . __('Disable or delete any plugin suspected to cause trouble, then log out and log back in normally.') . + '

'; + } else { + echo '
'; + } + + echo + '

' . + form::field('user_id', 20, 32, + [ + 'default' => html::escapeHTML($user_id), + 'autocomplete' => 'username' + ] + ) . '

' . + + '

' . + form::password('user_pwd', 20, 255, + [ + 'autocomplete' => 'current-password' + ] + ) . '

' . + + '

' . + form::checkbox('user_remember', 1) . + '

' . + + '

'; + + if (!empty($_REQUEST['blog'])) { + echo form::hidden('blog', html::escapeHTML($_REQUEST['blog'])); + } + if ($safe_mode) { + echo + form::hidden('safe_mode', 1) . + '
'; + } else { + echo '
'; + } + echo + ''; + + echo '
'; + + if ($safe_mode) { + echo + '

' . __('Get back to normal authentication') . '

'; + } else { + echo '

' . __('Connection issue?') . '

'; + if ($core->auth->allowPassChange()) { + echo '

' . __('I forgot my password') . '

'; + } + echo '

' . __('I want to log in in safe mode') . '

'; + } + + echo '
'; + } +} +?> +
+ + diff --git a/dotclear._no/admin/blog.php b/dotclear._no/admin/blog.php new file mode 100644 index 0000000..e4da0f4 --- /dev/null +++ b/dotclear._no/admin/blog.php @@ -0,0 +1,113 @@ +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 + '
' . + + '
' . $core->formNonce() . '
' . + '

' . + form::field('blog_id', 30, 32, + [ + 'default' => html::escapeHTML($blog_id), + 'extra_html' => 'required placeholder="' . __('Blog ID') . '"' + ] + ) . '

' . + '

' . __('At least 2 characters using letters, numbers or symbols.') . '

'; + + echo + '

' . + 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"' + ] + ) . '

' . + + '

' . + form::url('blog_url', + [ + 'size' => 30, + 'default' => html::escapeHTML($blog_url), + 'extra_html' => 'required placeholder="' . __('Blog URL') . '"' + ] + ) . '

' . + + '

' . + form::textarea('blog_desc', 60, 5, + [ + 'default' => html::escapeHTML($blog_desc), + 'extra_html' => 'lang="' . $core->auth->getInfo('user_lang') . '" spellcheck="true"' + ]) . '

' . + + '

' . + '
'; + + dcPage::helpBlock('core_blog_new'); + dcPage::close(); +} diff --git a/dotclear._no/admin/blog_del.php b/dotclear._no/admin/blog_del.php new file mode 100644 index 0000000..c5870c7 --- /dev/null +++ b/dotclear._no/admin/blog_del.php @@ -0,0 +1,74 @@ +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 + '

' . __('Warning') . '

' . + '

' . sprintf(__('You are about to delete the blog %s. Every entry, comment and category will be deleted.'), + '' . $blog_id . ' (' . $blog_name . ')') . '

' . + '

' . __('Please give your password to confirm the blog deletion.') . '

'; + + echo + '
' . + '
' . $core->formNonce() . '
' . + '

' . + form::password('pwd', 20, 255, ['autocomplete' => 'current-password']) . '

' . + '

' . + form::hidden('blog_id', $blog_id) . '

' . + '
'; +} + +dcPage::close(); diff --git a/dotclear._no/admin/blog_pref.php b/dotclear._no/admin/blog_pref.php new file mode 100644 index 0000000..db7df31 --- /dev/null +++ b/dotclear._no/admin/blog_pref.php @@ -0,0 +1,907 @@ +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 + '
' . + '

' . __('Blog parameters') . '

' . + '
'; + + echo + '

' . __('Blog details') . '

' . + $core->formNonce(); + + echo + '

' . + form::field('blog_name', 30, 255, + [ + 'default' => html::escapeHTML($blog_name), + 'extra_html' => 'required placeholder="' . __('Blog name') . ' lang="' . $blog_settings->system->lang . + '" spellcheck="true"' + ] + ) . '

'; + + echo + '

' . + form::textarea('blog_desc', 60, 5, + [ + 'default' => html::escapeHTML($blog_desc), + 'extra_html' => 'lang="' . $blog_settings->system->lang . '" spellcheck="true"' + ]) . '

'; + + if ($core->auth->isSuperAdmin()) { + echo + '

' . + form::combo('blog_status', $status_combo, $blog_status) . '

'; + + } 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 '
'; + + echo + '

' . __('Blog configuration') . '

' . + + '

' . + form::field('editor', 30, 255, html::escapeHTML($blog_settings->system->editor)) . + '

' . + + '

' . + form::combo('lang', $lang_combo, $blog_settings->system->lang, 'l10n') . + '

' . + + '

' . + form::combo('blog_timezone', dt::getZones(true, true), html::escapeHTML($blog_settings->system->blog_timezone)) . + '

' . + + '

' . + form::field('copyright_notice', 30, 255, + [ + 'default' => html::escapeHTML($blog_settings->system->copyright_notice), + 'extra_html' => 'lang="' . $blog_settings->system->lang . '" spellcheck="true"' + ]) . + '

' . + + '
'; + + echo + '

' . __('Comments and trackbacks') . '

' . + + '
' . + + '
' . + '

' . + '

' . + '

' . + '

' . __('No limit: leave blank.') . '

' . + '

' . + '

' . + '
' . + + '
' . + '

' . + '

' . + '

' . + '

' . __('No limit: leave blank.') . '

' . + '

' . + '
' . + '
' . //Opera sucks + + '
' . + '
' . //Opera sucks + '
'; + + echo + '

' . __('Blog presentation') . '

' . + '
' . + '
' . + '

' . + 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') . '"']) . + '

' . + '

' . __('Sample:') . ' ' . dt::str(html::escapeHTML($blog_settings->system->date_format)) . '

' . + + '

' . + 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') . '"']) . + '

' . + '

' . __('Sample:') . ' ' . dt::str(html::escapeHTML($blog_settings->system->time_format)) . '

' . + + '

' . + + '

' . + + '
' . + + '
' . + + '

' . + + '

' . + + '

' . + + '

' . + + '

' . + + '

' . + '
' . + '
' . + '
' . //Opera sucks + + '
' . + + '

' . + + '

' . + form::field('static_home_url', 30, 255, html::escapeHTML($blog_settings->system->static_home_url)) . + ' ' . + '

' . + '

' . __('Leave empty to use the default presentation.') . '

' . + + '
'; + + echo + '

' . __('Media and images') . '

' . + '

' . + __('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.') . '
' . + __('Set -1 to use the default size, set 0 to ignore this thumbnail size (images only).') . '

' . + + '
' . + '
' . + '
' . __('Generated image sizes (max dimension in pixels)') . '
' . + '

' . + form::number('media_img_t_size', [ + 'min' => -1, + 'max' => 999, + 'default' => $blog_settings->system->media_img_t_size + ]) . + '

' . + + '

' . + form::number('media_img_s_size', [ + 'min' => -1, + 'max' => 999, + 'default' => $blog_settings->system->media_img_s_size + ]) . + '

' . + + '

' . + form::number('media_img_m_size', [ + 'min' => -1, + 'max' => 999, + 'default' => $blog_settings->system->media_img_m_size + ]) . + '

' . + + '
' . __('Default size of the inserted video (in pixels)') . '
' . + '

' . + form::number('media_video_width', [ + 'min' => -1, + 'max' => 999, + 'default' => $blog_settings->system->media_video_width + ]) . + '

' . + + '

' . + form::number('media_video_height', [ + 'min' => -1, + 'max' => 999, + 'default' => $blog_settings->system->media_video_height + ]) . + '

' . + '
' . + + '
' . + '
' . __('Default image insertion attributes') . '
' . + '

' . + form::combo('media_img_title_pattern', $img_title_combo, html::escapeHTML($blog_settings->system->media_img_title_pattern)) . '

' . + '

' . + '

' . + '

' . __('It is retrieved from the picture\'s metadata.') . '

' . + + '

' . + 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')) . + '

' . + '

' . + form::combo('media_img_default_alignment', $img_default_alignment_combo, html::escapeHTML($blog_settings->system->media_img_default_alignment)) . + '

' . + '

' . + '

' . + form::combo('media_img_default_legend', $img_default_legend_combo, html::escapeHTML($blog_settings->system->media_img_default_legend)) . + '

' . + '
' . + '
' . + '
' . //Opera sucks + + '
' . + '
'; + + echo '

' . __('Advanced parameters') . '

'; + + if ($core->auth->isSuperAdmin()) { + echo '

' . __('Blog details') . '

'; + echo + '

' . + form::field('blog_id', 30, 32, html::escapeHTML($blog_id), '', '', false, 'required placeholder="' . __('Blog ID') . '"') . '

' . + '

' . __('At least 2 characters using letters, numbers or symbols.') . '

' . + '

' . __('Please note that changing your blog ID may require changes in your public index.php file.') . '

'; + + echo + '

' . + form::url('blog_url', [ + 'size' => 50, + 'max' => 255, + 'default' => html::escapeHTML($blog_url), + 'extra_html' => 'required placeholder="' . __('Blog URL') . '"' + ]) . + '

' . + + '

' . + form::combo('url_scan', $url_scan_combo, $blog_settings->system->url_scan) . '

'; + + 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 + '

' . + sprintf(__('The URL of blog or the URL scan method might not be well set (%s return a %s status).'), + html::escapeHTML($file), $status) . + '

'; + } else { + if (substr($content, 0, 6) != '' . + sprintf(__('The URL of blog or the URL scan method might not be well set (%s does not return an ATOM feed).'), + html::escapeHTML($file)) . + '

'; + } + } + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + echo '
'; + } + + echo + '

' . __('Blog configuration') . '

' . + + '

' . + form::combo('post_url_format', $post_url_combo, html::escapeHTML($blog_settings->system->post_url_format)) . + '

' . + '

' . __('Sample:') . ' ' . $core->blog->getPostURL('', date('Y-m-d H:i:00', $now), __('Dotclear'), 42) . '

' . + '

' . + + '

' . + form::combo('note_title_tag', $note_title_tag_combo, $blog_settings->system->note_title_tag) . + '

' . + + '

' . '

' . + '

' . __('XML/RPC interface allows you to edit your blog with an external client.') . '

'; + + if ($blog_settings->system->enable_xmlrpc) { + echo + '

' . __('XML/RPC interface is active. You should set the following parameters on your XML/RPC client:') . '

' . + '
    ' . + '
  • ' . __('Server URL:') . ' ' . + sprintf(DC_XMLRPC_URL, $core->blog->url, $core->blog->id) . + '
  • ' . + '
  • ' . __('Blogging system:') . ' Movable Type
  • ' . + '
  • ' . __('User name:') . ' ' . $core->auth->userID() . '
  • ' . + '
  • ' . __('Password:') . ' <' . __('your password') . '>
  • ' . + '
  • ' . __('Blog ID:') . ' 1
  • ' . + '
'; + } + + echo + '
'; + + // Search engines policies + echo '

' . __('Search engines robots policy') . '

'; + + $i = 0; + foreach ($robots_policy_options as $k => $v) { + echo '

'; + $i++; + } + + echo '
'; + + echo '

' . __('jQuery javascript library') . '

' . + + '

' . + + '

' . ' ' . + form::combo('jquery_version', $jquery_versions_combo, $blog_settings->system->jquery_version) . + '

' . + '
' . //Opera sucks + + '
'; + + echo '

' . __('Blog security') . '

' . + + '

' . + '
' . //Opera sucks + + '
'; + + echo '
'; // End advanced + + echo '

' . __('Plugins parameters') . '

'; + + # --BEHAVIOR-- adminBlogPreferencesForm + $core->callBehavior('adminBlogPreferencesForm', $core, $blog_settings); + + echo '
'; // End 3rd party, aka plugins + + echo + '

' . + (!$standalone ? form::hidden('id', $blog_id) : '') . + '

' . + ''; + + if ($core->auth->isSuperAdmin() && $blog_id != $core->blog->id) { + echo + '
' . + '

' . + form::hidden(['blog_id'], $blog_id) . + $core->formNonce() . '

' . + '
'; + } else { + if ($blog_id == $core->blog->id) { + echo '

' . __('The current blog cannot be deleted.') . '

'; + } else { + echo '

' . __('Only superadmin can delete a blog.') . '

'; + } + } + + echo '
'; + + # + # Users on the blog (with permissions) + + $blog_users = $core->getBlogPermissions($blog_id, $core->auth->isSuperAdmin()); + $perm_types = $core->auth->getPermissionsTypes(); + + echo + '
' . + '

' . __('Users on this blog') . '

'; + + if (empty($blog_users)) { + echo '

' . __('No users') . '

'; + } else { + if ($core->auth->isSuperAdmin()) { + $user_url_p = ' '%1$s'], '&', true) . '">%1$s'; + } 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 '
'; + foreach ($blog_users as $k => $v) { + if (count($v['p']) > 0) { + echo + '
' . + '

' . sprintf($user_url_p, html::escapeHTML($k)) . + ' (' . html::escapeHTML(dcUtils::getUserCN( + $k, $v['name'], $v['firstname'], $v['displayname'] + )) . ')

'; + + if ($core->auth->isSuperAdmin()) { + echo + '

' . __('Email:') . ' ' . + ($v['email'] != '' ? '' . $v['email'] . '' : __('(none)')) . + '

'; + } + + echo + '
' . __('Publications on this blog:') . '
' . + '
    '; + foreach ($post_type as $type => $pt_info) { + $params = [ + 'post_type' => $type, + 'user_id' => $k + ]; + echo '
  • ' . sprintf(__('%1$s: %2$s'), __($pt_info['label']), $core->blog->getPosts($params, true)->f(0)) . '
  • '; + } + echo + '
'; + + echo + '
' . __('Permissions:') . '
' . + '
    '; + if ($v['super']) { + echo '
  • ' . __('Super administrator') . '
    ' . + '' . __('All rights on all blogs.') . '
  • '; + } else { + foreach ($v['p'] as $p => $V) { + if (isset($perm_types[$p])) { + echo '
  • ' . __($perm_types[$p]); + } else { + echo '
  • ' . sprintf(__('[%s] (unreferenced permission)'), $p); + } + + if ($p == 'admin') { + echo '
    ' . __('All rights on this blog.') . ''; + } + echo '
  • '; + } + } + echo + '
'; + + if (!$v['super'] && $core->auth->isSuperAdmin()) { + echo + '
' . + '

' . + 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() . + '

' . + '
'; + } + echo '
'; + } + } + echo '
'; + if ($current_blog_id != $core->blog->id) { + $core->setBlog($current_blog_id); + } + } + + echo '
'; +} + +dcPage::helpBlock('core_blog_pref'); +dcPage::close(); diff --git a/dotclear._no/admin/blog_theme.php b/dotclear._no/admin/blog_theme.php new file mode 100644 index 0000000..dd0e760 --- /dev/null +++ b/dotclear._no/admin/blog_theme.php @@ -0,0 +1,250 @@ +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), + '' . __('Theme configuration') . '' => '' + ]) + ); + + # 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) => '', + '' . __('Blog appearance') . '' => '' + ]) +); + +# -- 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 + '
' . + '

' . html::escapeHTML(__('Update themes')) . '

' . + '

' . sprintf( + __('There is one theme to update available from repository.', 'There are %s themes to update available from repository.', count($modules)), + count($modules) + ) . '

'; + + $list + ->setList('theme-update') + ->setTab('themes') + ->setModules($modules) + ->displayModules( + /*cols */['checkbox', 'name', 'sshot', 'desc', 'author', 'version', 'current_version', 'parent'], + /* actions */['update', 'delete'] + ); + + echo + '

' . sprintf( + __("Visit %s repository, the resources center for Dotclear."), + 'Dotaddict' + ) . + '

' . + + '
'; + } else { + echo + '
' . + '

' . + '

' . + '
'; + } +} + +# Activated modules +$modules = $list->modules->getModules(); +if (!empty($modules)) { + + echo + '
' . + '

' . __('Installed themes') . '

' . + '

' . __('You can configure and manage installed themes from this list.') . '

'; + + $list + ->setList('theme-activate') + ->setTab('themes') + ->setModules($modules) + ->displayModules( + /* cols */['sshot', 'distrib', 'name', 'config', 'desc', 'author', 'version', 'parent'], + /* actions */['select', 'behavior', 'deactivate', 'delete'] + ); + + echo + '
'; +} + +# Deactivated modules +$modules = $list->modules->getDisabledModules(); +if (!empty($modules)) { + + echo + '
' . + '

' . __('Deactivated themes') . '

' . + '

' . __('Deactivated themes are installed but not usable. You can activate them from here.') . '

'; + + $list + ->setList('theme-deactivate') + ->setTab('themes') + ->setModules($modules) + ->displayModules( + /* cols */['name', 'distrib'], + /* actions */['activate', 'delete'] + ); + + echo + '
'; +} + +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 + '
' . + '

' . __('Add themes from repository') . '

'; +// '

'.__('Search and install themes directly from repository.').'

'; + + $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 + '

' . sprintf( + __("Visit %s repository, the resources center for Dotclear."), + 'Dotaddict' + ) . + '

' . + + '
'; + } + + # Add a new plugin + echo + '
' . + '

' . __('Add themes from a package') . '

' . + '

' . __('You can install themes by uploading or downloading zip files.') . '

'; + + $list->displayManualForm(); + + echo + '
'; +} + +# --BEHAVIOR-- themesToolsTabs +$core->callBehavior('themesToolsTabs', $core); + +# -- Notice for super admin -- +if ($core->auth->isSuperAdmin() && !$list->isWritablePath()) { + echo + '

' . __('Some functions are disabled, please give write access to your themes directory to enable them.') . '

'; +} + +dcPage::helpBlock('core_blog_theme'); +dcPage::close(); diff --git a/dotclear._no/admin/blogs.php b/dotclear._no/admin/blogs.php new file mode 100644 index 0000000..5868452 --- /dev/null +++ b/dotclear._no/admin/blogs.php @@ -0,0 +1,185 @@ + ''], + 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 '

' . __('Create a new blog') . '

'; + } + + echo + '
' . + '

' . __('Show filters and display options') . '

' . + + '
' . + '
' . + '

' . __('Filters') . '

' . + '

' . + form::field('q', 20, 255, html::escapeHTML($q)) . '

' . + ($core->auth->isSuperAdmin() ? + '

' . + form::combo('status', $status_combo, $status) . '

' : '') . + '
' . + + '
' . + '

' . __('Display options') . '

' . + '

' . + form::combo('sortby', $sortby_combo, html::escapeHTML($sortby)) . '

' . + '

' . + form::combo('order', $order_combo, html::escapeHTML($order)) . '

' . + '

' . __('Show') . '

' . + '
' . + '
' . + + '

' . + '

' . //Opera sucks + '
'; + + # Show blogs + $blog_list->display($page, $nb_per_page, + ($core->auth->isSuperAdmin() ? + '
' : '') . + + '%s' . + + ($core->auth->isSuperAdmin() ? + '
' . + '

' . + + '

' . + form::combo('action', $blogs_actions_page->getCombo(), + ['class' => 'online', 'extra_html' => 'title="' . __('Actions') . '"']) . + $core->formNonce() . + '

' . + '
' . + + '

' . + form::password('pwd', 20, 255, ['autocomplete' => 'current-password']) . '

' . + + form::hidden(['sortby'], $sortby) . + form::hidden(['order'], $order) . + form::hidden(['status'], $status) . + form::hidden(['page'], $page) . + form::hidden(['nb'], $nb_per_page) . + + '
' : ''), + $show_filters + ); +} + +dcPage::helpBlock('core_blogs'); +dcPage::close(); diff --git a/dotclear._no/admin/categories.php b/dotclear._no/admin/categories.php new file mode 100644 index 0000000..0da54a6 --- /dev/null +++ b/dotclear._no/admin/categories.php @@ -0,0 +1,219 @@ +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 +'

' . __('New category') . '

'; + +echo + '
'; +if ($rs->isEmpty()) { + echo '

' . __('No category so far.') . '

'; +} else { + echo + '
' . + '
'; + + $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('
  • ', $rs->level - $level); + } elseif ($rs->level < $level) { + echo str_repeat('
', -($rs->level - $level)); + } + + if ($rs->level <= $level) { + echo '
  • '; + } + + echo + '

    ' . + '

    ( $rs->cat_id]) . '">' . + sprintf(($rs->nb_post > 1 ? __('%d entries') : __('%d entry')), $rs->nb_post) . '' . + ', ' . __('total:') . ' ' . $rs->nb_total . ')

    ' . + '

    ' . __('URL:') . ' ' . html::escapeHTML($rs->cat_url) . '

    '; + + echo + '

    '; + if ($rs->nb_total > 0) { + // remove current category + echo + ' ' . + 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;} + ), '', '') . + ' '; + + $attr_disabled = ' disabled="disabled"'; + $input_class = 'disabled '; + } else { + $attr_disabled = ''; + $input_class = ''; + } + echo + ' ' . + '

    '; + + $level = $rs->level; + } + + if ($ref_level - $level < 0) { + echo str_repeat('
  • ', -($ref_level - $level)); + } + echo + '
    '; + + echo '
    '; + + if ($core->auth->check('categories', $core->blog->id) && $rs->count() > 1) { + if (!$core->auth->user_prefs->accessibility->nodragdrop) { + echo '

    ' . __('To rearrange categories order, move items by drag and drop, then click on “Save categories order” button.') . '

    '; + } + echo + '

    ' . + '' . + '' . + ' '; + } else { + echo '

    '; + } + + echo + '' . + $core->formNonce() . '

    ' . + '
    '; +} + +echo '
    '; + +dcPage::helpBlock('core_categories'); +dcPage::close(); diff --git a/dotclear._no/admin/category.php b/dotclear._no/admin/category.php new file mode 100644 index 0000000..a0bf007 --- /dev/null +++ b/dotclear._no/admin/category.php @@ -0,0 +1,263 @@ +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 +'
    ' . +'

    ' . __('Category information') . '

    ' . +'

    ' . +form::field('cat_title', 40, 255, [ + 'default' => html::escapeHTML($cat_title), + 'extra_html' => 'required placeholder="' . __('Name') . '" lang="' . $blog_lang . '" spellcheck="true"' +]) . + '

    '; +if (!$cat_id) { + $rs = $core->blog->getCategories(); + echo + '

    '; + unset($rs); +} +echo +'
    ' . +'

    ' +. form::field('cat_url', 40, 255, html::escapeHTML($cat_url)) . +'

    ' . +'

    ' . +__('Warning: If you set the URL manually, it may conflict with another category.') . '

    ' . +'
    ' . + +'

    ' . +form::textarea('cat_desc', 50, 8, + [ + 'default' => html::escapeHTML($cat_desc), + 'extra_html' => 'lang="' . $blog_lang . '" spellcheck="true"' + ]) . +'

    ' . + +'

    ' . +($cat_id ? form::hidden('id', $cat_id) : '') . +$core->formNonce() . + '

    ' . + '
    '; + +if ($cat_id) { + echo + '

    ' . __('Move this category') . '

    ' . + '
    ' . + '
    ' . + + '
    ' . + '

    ' . __('Category parent') . '

    ' . + '

    ' . + form::combo('cat_parent', $allowed_parents, $cat_parent) . '

    ' . + '

    ' . + form::hidden(['id'], $cat_id) . $core->formNonce() . '

    ' . + '
    ' . + '
    '; + + if (count($siblings) > 0) { + echo + '
    ' . + '
    ' . + '

    ' . __('Category sibling') . '

    ' . + '

    ' . + form::combo('cat_move', [__('before') => 'before', __('after') => 'after'], + ['extra_html' => 'title="' . __('position: ') . '"']) . ' ' . + form::combo('cat_sibling', $siblings) . '

    ' . + '

    ' . + form::hidden(['id'], $cat_id) . $core->formNonce() . '

    ' . + '
    ' . + '
    '; + } + + echo '
    '; +} + +dcPage::helpBlock('core_category'); +dcPage::close(); diff --git a/dotclear._no/admin/comment.php b/dotclear._no/admin/comment.php new file mode 100644 index 0000000..ea4caa5 --- /dev/null +++ b/dotclear._no/admin/comment.php @@ -0,0 +1,252 @@ +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 = 'getPostURL())) + . '">' . __('Send an e-mail') . ''; + } + + echo + '
    ' . + '
    ' . + '

    ' . __('Information collected') . '

    ' . + '

    ' . __('IP address:') . ' ' . + ' $comment_ip]) . '">' . $comment_ip . '

    ' . + + '

    ' . __('Date:') . ' ' . + dt::dt2str(__('%Y-%m-%d %H:%M'), $comment_dt) . '

    ' . + '
    ' . + + '

    ' . __('Comment submitted') . '

    ' . + '

    ' . + form::field('comment_author', 30, 255, [ + 'default' => html::escapeHTML($comment_author), + 'extra_html' => 'required placeholder="' . __('Author') . '"' + ]) . + '

    ' . + + '

    ' . + form::email('comment_email', 30, 255, html::escapeHTML($comment_email)) . + '' . $comment_mailto . '' . + '

    ' . + + '

    ' . + form::url('comment_site', 30, 255, html::escapeHTML($comment_site)) . + '

    ' . + + '

    ' . + form::combo('comment_status', $status_combo, + ['default' => $comment_status, 'disabled' => !$can_publish]) . + '

    ' . + + # --BEHAVIOR-- adminAfterCommentDesc + $core->callBehavior('adminAfterCommentDesc', $rs) . + + '

    ' . + form::textarea('comment_content', 50, 10, + [ + 'default' => html::escapeHTML($comment_content), + 'extra_html' => 'lang="' . $core->auth->getInfo('user_lang') . '" spellcheck="true"' + ]) . + '

    ' . + + '

    ' . form::hidden('id', $comment_id) . + $core->formNonce() . + ' '; + + if ($can_delete) { + echo ''; + } + echo + '

    ' . + '
    '; +} + +dcPage::helpBlock('core_comments'); +dcPage::close(); diff --git a/dotclear._no/admin/comments.php b/dotclear._no/admin/comments.php new file mode 100644 index 0000000..a8e88af --- /dev/null +++ b/dotclear._no/admin/comments.php @@ -0,0 +1,302 @@ +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 + '
    '; + + if (!$with_spam || ($status != -2)) { + if ($spam_count == 1) { + echo '

    ' . sprintf(__('You have one spam comment.'), '' . $spam_count . '') . ' ' . + ' -2]) . '">' . __('Show it.') . '

    '; + } elseif ($spam_count > 1) { + echo '

    ' . sprintf(__('You have %s spam comments.'), '' . $spam_count . '') . ' ' . + ' -2]) . '">' . __('Show them.') . '

    '; + } + } + + echo + '

    ' . + $core->formNonce() . + '

    '; + + # --BEHAVIOR-- adminCommentsSpamForm + $core->callBehavior('adminCommentsSpamForm', $core); + + echo '
    '; + } + + echo + '
    ' . + '

    ' . __('Show filters and display options') . '

    ' . + + '
    ' . + '
    ' . + '

    ' . __('Filters') . '

    ' . + '

    ' . + form::combo('type', $type_combo, $type) . '

    ' . + '

    ' . + form::combo('status', $status_combo, $status) . '

    ' . + '
    ' . + + '
    ' . + '

    ' . + form::field('author', 20, 255, html::escapeHTML($author)) . '

    ' . + '

    ' . + form::field('ip', 20, 39, html::escapeHTML($ip)) . '

    ' . + '

    ' . + form::field('email', 20, 255, html::escapeHTML($email)) . '

    ' . + '

    ' . + form::field('site', 20, 255, html::escapeHTML($site)) . '

    ' . + '
    ' . + + '
    ' . + '

    ' . __('Display options') . '

    ' . + '

    ' . + form::combo('sortby', $sortby_combo, $sortby) . '

    ' . + '

    ' . + form::combo('order', $order_combo, $order) . '

    ' . + '

    ' . __('Show') . '

    ' . + '
    ' . + + '
    ' . + '

    ' . + '

    ' . //Opera sucks + '
    '; + + # Show comments + $comment_list->display($page, $nb_per_page, + '
    ' . + + '%s' . + + '
    ' . + '

    ' . + + '

    ' . + form::combo('action', $comments_actions_page->getCombo(), + ['default' => $default, 'extra_html' => 'title="' . __('Actions') . '"']) . + $core->formNonce() . + '

    ' . + 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))) . + '
    ' . + + '
    ', + $show_filters, + ($with_spam || ($status == -2)) + ); +} + +dcPage::helpBlock('core_comments'); +dcPage::close(); diff --git a/dotclear._no/admin/comments_actions.php b/dotclear._no/admin/comments_actions.php new file mode 100644 index 0000000..fd5238a --- /dev/null +++ b/dotclear._no/admin/comments_actions.php @@ -0,0 +1,30 @@ +adminurl->get("admin.comments"); + $args = []; +} + +$comments_actions_page = new dcCommentsActionsPage($core, $uri, $args); +$comments_actions_page->setEnableRedirSelection(false); +$comments_actions_page->process(); diff --git a/dotclear._no/admin/csp_report.php b/dotclear._no/admin/csp_report.php new file mode 100644 index 0000000..acc929b --- /dev/null +++ b/dotclear._no/admin/csp_report.php @@ -0,0 +1,106 @@ + 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(,true); + fprintf($fp, ($contents != '' ? ',' : '') . '%s', $output); + + } catch (Exception $e) { + return; + } + } +} diff --git a/dotclear._no/admin/dispatcher.php b/dotclear._no/admin/dispatcher.php new file mode 100755 index 0000000..9c923ab --- /dev/null +++ b/dotclear._no/admin/dispatcher.php @@ -0,0 +1,34 @@ +What the hell are you doing here?

    '; +exit; +?> \ No newline at end of file diff --git a/dotclear._no/admin/help.php b/dotclear._no/admin/help.php new file mode 100644 index 0000000..fe86a0b --- /dev/null +++ b/dotclear._no/admin/help.php @@ -0,0 +1,95 @@ + '', '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('|]*?>(.*?)|ms', $fc, $matches)) { + $content .= $matches[1]; + if (preg_match('|]*?>(.*?)|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(); diff --git a/dotclear._no/admin/images/add.png b/dotclear._no/admin/images/add.png new file mode 100755 index 0000000..e892690 Binary files /dev/null and b/dotclear._no/admin/images/add.png differ diff --git a/dotclear._no/admin/images/admin.png b/dotclear._no/admin/images/admin.png new file mode 100644 index 0000000..1f99b96 Binary files /dev/null and b/dotclear._no/admin/images/admin.png differ diff --git a/dotclear._no/admin/images/attach.png b/dotclear._no/admin/images/attach.png new file mode 100644 index 0000000..ac3731c Binary files /dev/null and b/dotclear._no/admin/images/attach.png differ diff --git a/dotclear._no/admin/images/attach.svg b/dotclear._no/admin/images/attach.svg new file mode 100644 index 0000000..5a73191 --- /dev/null +++ b/dotclear._no/admin/images/attach.svg @@ -0,0 +1 @@ +attachment diff --git a/dotclear._no/admin/images/check-off.png b/dotclear._no/admin/images/check-off.png new file mode 100644 index 0000000..2efea6c Binary files /dev/null and b/dotclear._no/admin/images/check-off.png differ diff --git a/dotclear._no/admin/images/check-on.png b/dotclear._no/admin/images/check-on.png new file mode 100644 index 0000000..499830c Binary files /dev/null and b/dotclear._no/admin/images/check-on.png differ diff --git a/dotclear._no/admin/images/check-wrn.png b/dotclear._no/admin/images/check-wrn.png new file mode 100644 index 0000000..ae5bd56 Binary files /dev/null and b/dotclear._no/admin/images/check-wrn.png differ diff --git a/dotclear._no/admin/images/close.png b/dotclear._no/admin/images/close.png new file mode 100755 index 0000000..731c64f Binary files /dev/null and b/dotclear._no/admin/images/close.png differ diff --git a/dotclear._no/admin/images/collapser-hide.png b/dotclear._no/admin/images/collapser-hide.png new file mode 100644 index 0000000..25a774d Binary files /dev/null and b/dotclear._no/admin/images/collapser-hide.png differ diff --git a/dotclear._no/admin/images/collapser-show.png b/dotclear._no/admin/images/collapser-show.png new file mode 100644 index 0000000..3fe082d Binary files /dev/null and b/dotclear._no/admin/images/collapser-show.png differ diff --git a/dotclear._no/admin/images/comments.png b/dotclear._no/admin/images/comments.png new file mode 100644 index 0000000..1a74669 Binary files /dev/null and b/dotclear._no/admin/images/comments.png differ diff --git a/dotclear._no/admin/images/date-picker.png b/dotclear._no/admin/images/date-picker.png new file mode 100644 index 0000000..55d9d07 Binary files /dev/null and b/dotclear._no/admin/images/date-picker.png differ diff --git a/dotclear._no/admin/images/disabled_down.png b/dotclear._no/admin/images/disabled_down.png new file mode 100644 index 0000000..1790f44 Binary files /dev/null and b/dotclear._no/admin/images/disabled_down.png differ diff --git a/dotclear._no/admin/images/disabled_up.png b/dotclear._no/admin/images/disabled_up.png new file mode 100644 index 0000000..24a7231 Binary files /dev/null and b/dotclear._no/admin/images/disabled_up.png differ diff --git a/dotclear._no/admin/images/dotclear_pw.png b/dotclear._no/admin/images/dotclear_pw.png new file mode 100644 index 0000000..c5cd279 Binary files /dev/null and b/dotclear._no/admin/images/dotclear_pw.png differ diff --git a/dotclear._no/admin/images/down.png b/dotclear._no/admin/images/down.png new file mode 100644 index 0000000..e366962 Binary files /dev/null and b/dotclear._no/admin/images/down.png differ diff --git a/dotclear._no/admin/images/dragndrop.svg b/dotclear._no/admin/images/dragndrop.svg new file mode 100644 index 0000000..bf72a46 --- /dev/null +++ b/dotclear._no/admin/images/dragndrop.svg @@ -0,0 +1,11 @@ + + + + + + diff --git a/dotclear._no/admin/images/edit-mini.png b/dotclear._no/admin/images/edit-mini.png new file mode 100644 index 0000000..94501c8 Binary files /dev/null and b/dotclear._no/admin/images/edit-mini.png differ diff --git a/dotclear._no/admin/images/expand.png b/dotclear._no/admin/images/expand.png new file mode 100644 index 0000000..a9b8e0e Binary files /dev/null and b/dotclear._no/admin/images/expand.png differ diff --git a/dotclear._no/admin/images/fav-off.png b/dotclear._no/admin/images/fav-off.png new file mode 100644 index 0000000..73ccd22 Binary files /dev/null and b/dotclear._no/admin/images/fav-off.png differ diff --git a/dotclear._no/admin/images/fav-on.png b/dotclear._no/admin/images/fav-on.png new file mode 100644 index 0000000..d848c7e Binary files /dev/null and b/dotclear._no/admin/images/fav-on.png differ diff --git a/dotclear._no/admin/images/favicon.ico b/dotclear._no/admin/images/favicon.ico new file mode 100644 index 0000000..284fc94 Binary files /dev/null and b/dotclear._no/admin/images/favicon.ico differ diff --git a/dotclear._no/admin/images/favicon.png b/dotclear._no/admin/images/favicon.png new file mode 100755 index 0000000..01fa2e2 Binary files /dev/null and b/dotclear._no/admin/images/favicon.png differ diff --git a/dotclear._no/admin/images/favicon96-login.png b/dotclear._no/admin/images/favicon96-login.png new file mode 100644 index 0000000..6d1626d Binary files /dev/null and b/dotclear._no/admin/images/favicon96-login.png differ diff --git a/dotclear._no/admin/images/favicon96-logout.png b/dotclear._no/admin/images/favicon96-logout.png new file mode 100644 index 0000000..ac70cf4 Binary files /dev/null and b/dotclear._no/admin/images/favicon96-logout.png differ diff --git a/dotclear._no/admin/images/grid-off.png b/dotclear._no/admin/images/grid-off.png new file mode 100755 index 0000000..fcf581e Binary files /dev/null and b/dotclear._no/admin/images/grid-off.png differ diff --git a/dotclear._no/admin/images/grid-on.png b/dotclear._no/admin/images/grid-on.png new file mode 100755 index 0000000..a8fa472 Binary files /dev/null and b/dotclear._no/admin/images/grid-on.png differ diff --git a/dotclear._no/admin/images/help.png b/dotclear._no/admin/images/help.png new file mode 100644 index 0000000..57c87c2 Binary files /dev/null and b/dotclear._no/admin/images/help.png differ diff --git a/dotclear._no/admin/images/hidden.png b/dotclear._no/admin/images/hidden.png new file mode 100644 index 0000000..5e0d5fc Binary files /dev/null and b/dotclear._no/admin/images/hidden.png differ diff --git a/dotclear._no/admin/images/hide.png b/dotclear._no/admin/images/hide.png new file mode 100644 index 0000000..b2829d6 Binary files /dev/null and b/dotclear._no/admin/images/hide.png differ diff --git a/dotclear._no/admin/images/junk.png b/dotclear._no/admin/images/junk.png new file mode 100644 index 0000000..805cba7 Binary files /dev/null and b/dotclear._no/admin/images/junk.png differ diff --git a/dotclear._no/admin/images/list-off.png b/dotclear._no/admin/images/list-off.png new file mode 100755 index 0000000..9f9443e Binary files /dev/null and b/dotclear._no/admin/images/list-off.png differ diff --git a/dotclear._no/admin/images/list-on.png b/dotclear._no/admin/images/list-on.png new file mode 100755 index 0000000..f63fda2 Binary files /dev/null and b/dotclear._no/admin/images/list-on.png differ diff --git a/dotclear._no/admin/images/locker.png b/dotclear._no/admin/images/locker.png new file mode 100644 index 0000000..9948fd7 Binary files /dev/null and b/dotclear._no/admin/images/locker.png differ diff --git a/dotclear._no/admin/images/logout.png b/dotclear._no/admin/images/logout.png new file mode 100644 index 0000000..9840f6e Binary files /dev/null and b/dotclear._no/admin/images/logout.png differ diff --git a/dotclear._no/admin/images/media/audio.png b/dotclear._no/admin/images/media/audio.png new file mode 100644 index 0000000..a160cf1 Binary files /dev/null and b/dotclear._no/admin/images/media/audio.png differ diff --git a/dotclear._no/admin/images/media/blank.png b/dotclear._no/admin/images/media/blank.png new file mode 100644 index 0000000..5a91f16 Binary files /dev/null and b/dotclear._no/admin/images/media/blank.png differ diff --git a/dotclear._no/admin/images/media/document.png b/dotclear._no/admin/images/media/document.png new file mode 100644 index 0000000..54f8bdd Binary files /dev/null and b/dotclear._no/admin/images/media/document.png differ diff --git a/dotclear._no/admin/images/media/executable.png b/dotclear._no/admin/images/media/executable.png new file mode 100644 index 0000000..b7582d3 Binary files /dev/null and b/dotclear._no/admin/images/media/executable.png differ diff --git a/dotclear._no/admin/images/media/folder-up.png b/dotclear._no/admin/images/media/folder-up.png new file mode 100644 index 0000000..23174dd Binary files /dev/null and b/dotclear._no/admin/images/media/folder-up.png differ diff --git a/dotclear._no/admin/images/media/folder.png b/dotclear._no/admin/images/media/folder.png new file mode 100644 index 0000000..2055bd2 Binary files /dev/null and b/dotclear._no/admin/images/media/folder.png differ diff --git a/dotclear._no/admin/images/media/html.png b/dotclear._no/admin/images/media/html.png new file mode 100644 index 0000000..a1d86ea Binary files /dev/null and b/dotclear._no/admin/images/media/html.png differ diff --git a/dotclear._no/admin/images/media/image.png b/dotclear._no/admin/images/media/image.png new file mode 100644 index 0000000..ce450f4 Binary files /dev/null and b/dotclear._no/admin/images/media/image.png differ diff --git a/dotclear._no/admin/images/media/package.png b/dotclear._no/admin/images/media/package.png new file mode 100644 index 0000000..fb1be90 Binary files /dev/null and b/dotclear._no/admin/images/media/package.png differ diff --git a/dotclear._no/admin/images/media/presentation.png b/dotclear._no/admin/images/media/presentation.png new file mode 100644 index 0000000..26d4173 Binary files /dev/null and b/dotclear._no/admin/images/media/presentation.png differ diff --git a/dotclear._no/admin/images/media/spreadsheet.png b/dotclear._no/admin/images/media/spreadsheet.png new file mode 100644 index 0000000..0e4e1d4 Binary files /dev/null and b/dotclear._no/admin/images/media/spreadsheet.png differ diff --git a/dotclear._no/admin/images/media/text.png b/dotclear._no/admin/images/media/text.png new file mode 100644 index 0000000..3b31bba Binary files /dev/null and b/dotclear._no/admin/images/media/text.png differ diff --git a/dotclear._no/admin/images/media/video.png b/dotclear._no/admin/images/media/video.png new file mode 100644 index 0000000..0ffc31d Binary files /dev/null and b/dotclear._no/admin/images/media/video.png differ diff --git a/dotclear._no/admin/images/menu/add_to_favorites.png b/dotclear._no/admin/images/menu/add_to_favorites.png new file mode 100755 index 0000000..43c807e Binary files /dev/null and b/dotclear._no/admin/images/menu/add_to_favorites.png differ diff --git a/dotclear._no/admin/images/menu/blog-pref-b.png b/dotclear._no/admin/images/menu/blog-pref-b.png new file mode 100644 index 0000000..6822513 Binary files /dev/null and b/dotclear._no/admin/images/menu/blog-pref-b.png differ diff --git a/dotclear._no/admin/images/menu/blog-pref.png b/dotclear._no/admin/images/menu/blog-pref.png new file mode 100644 index 0000000..5a818f6 Binary files /dev/null and b/dotclear._no/admin/images/menu/blog-pref.png differ diff --git a/dotclear._no/admin/images/menu/blog-theme-b-update.png b/dotclear._no/admin/images/menu/blog-theme-b-update.png new file mode 100644 index 0000000..138548a Binary files /dev/null and b/dotclear._no/admin/images/menu/blog-theme-b-update.png differ diff --git a/dotclear._no/admin/images/menu/blog-theme-b.png b/dotclear._no/admin/images/menu/blog-theme-b.png new file mode 100644 index 0000000..89d95f5 Binary files /dev/null and b/dotclear._no/admin/images/menu/blog-theme-b.png differ diff --git a/dotclear._no/admin/images/menu/blogs-b.png b/dotclear._no/admin/images/menu/blogs-b.png new file mode 100644 index 0000000..d53ca8c Binary files /dev/null and b/dotclear._no/admin/images/menu/blogs-b.png differ diff --git a/dotclear._no/admin/images/menu/blogs.png b/dotclear._no/admin/images/menu/blogs.png new file mode 100644 index 0000000..700b42d Binary files /dev/null and b/dotclear._no/admin/images/menu/blogs.png differ diff --git a/dotclear._no/admin/images/menu/categories-b.png b/dotclear._no/admin/images/menu/categories-b.png new file mode 100644 index 0000000..0014c7c Binary files /dev/null and b/dotclear._no/admin/images/menu/categories-b.png differ diff --git a/dotclear._no/admin/images/menu/categories.png b/dotclear._no/admin/images/menu/categories.png new file mode 100644 index 0000000..239764f Binary files /dev/null and b/dotclear._no/admin/images/menu/categories.png differ diff --git a/dotclear._no/admin/images/menu/comments-b.png b/dotclear._no/admin/images/menu/comments-b.png new file mode 100644 index 0000000..ee50486 Binary files /dev/null and b/dotclear._no/admin/images/menu/comments-b.png differ diff --git a/dotclear._no/admin/images/menu/comments.png b/dotclear._no/admin/images/menu/comments.png new file mode 100644 index 0000000..6ff1ed4 Binary files /dev/null and b/dotclear._no/admin/images/menu/comments.png differ diff --git a/dotclear._no/admin/images/menu/dashboard.png b/dotclear._no/admin/images/menu/dashboard.png new file mode 100755 index 0000000..95a9ac4 Binary files /dev/null and b/dotclear._no/admin/images/menu/dashboard.png differ diff --git a/dotclear._no/admin/images/menu/edit-b.png b/dotclear._no/admin/images/menu/edit-b.png new file mode 100644 index 0000000..1f3f7de Binary files /dev/null and b/dotclear._no/admin/images/menu/edit-b.png differ diff --git a/dotclear._no/admin/images/menu/edit.png b/dotclear._no/admin/images/menu/edit.png new file mode 100644 index 0000000..c9d446a Binary files /dev/null and b/dotclear._no/admin/images/menu/edit.png differ diff --git a/dotclear._no/admin/images/menu/entries-b.png b/dotclear._no/admin/images/menu/entries-b.png new file mode 100644 index 0000000..028e2c4 Binary files /dev/null and b/dotclear._no/admin/images/menu/entries-b.png differ diff --git a/dotclear._no/admin/images/menu/entries.png b/dotclear._no/admin/images/menu/entries.png new file mode 100644 index 0000000..188b505 Binary files /dev/null and b/dotclear._no/admin/images/menu/entries.png differ diff --git a/dotclear._no/admin/images/menu/favorite-b.png b/dotclear._no/admin/images/menu/favorite-b.png new file mode 100755 index 0000000..a2dca4c Binary files /dev/null and b/dotclear._no/admin/images/menu/favorite-b.png differ diff --git a/dotclear._no/admin/images/menu/favorite.png b/dotclear._no/admin/images/menu/favorite.png new file mode 100755 index 0000000..0c98780 Binary files /dev/null and b/dotclear._no/admin/images/menu/favorite.png differ diff --git a/dotclear._no/admin/images/menu/help-b.png b/dotclear._no/admin/images/menu/help-b.png new file mode 100644 index 0000000..dbd43bb Binary files /dev/null and b/dotclear._no/admin/images/menu/help-b.png differ diff --git a/dotclear._no/admin/images/menu/help.png b/dotclear._no/admin/images/menu/help.png new file mode 100644 index 0000000..b51692a Binary files /dev/null and b/dotclear._no/admin/images/menu/help.png differ diff --git a/dotclear._no/admin/images/menu/langs-b.png b/dotclear._no/admin/images/menu/langs-b.png new file mode 100644 index 0000000..415a0ac Binary files /dev/null and b/dotclear._no/admin/images/menu/langs-b.png differ diff --git a/dotclear._no/admin/images/menu/langs.png b/dotclear._no/admin/images/menu/langs.png new file mode 100644 index 0000000..0470293 Binary files /dev/null and b/dotclear._no/admin/images/menu/langs.png differ diff --git a/dotclear._no/admin/images/menu/media-b.png b/dotclear._no/admin/images/menu/media-b.png new file mode 100644 index 0000000..1071c66 Binary files /dev/null and b/dotclear._no/admin/images/menu/media-b.png differ diff --git a/dotclear._no/admin/images/menu/media.png b/dotclear._no/admin/images/menu/media.png new file mode 100644 index 0000000..244bcec Binary files /dev/null and b/dotclear._no/admin/images/menu/media.png differ diff --git a/dotclear._no/admin/images/menu/plugins-b-update.png b/dotclear._no/admin/images/menu/plugins-b-update.png new file mode 100644 index 0000000..d0987fe Binary files /dev/null and b/dotclear._no/admin/images/menu/plugins-b-update.png differ diff --git a/dotclear._no/admin/images/menu/plugins-b.png b/dotclear._no/admin/images/menu/plugins-b.png new file mode 100644 index 0000000..b72064e Binary files /dev/null and b/dotclear._no/admin/images/menu/plugins-b.png differ diff --git a/dotclear._no/admin/images/menu/plugins.png b/dotclear._no/admin/images/menu/plugins.png new file mode 100644 index 0000000..9b29cb1 Binary files /dev/null and b/dotclear._no/admin/images/menu/plugins.png differ diff --git a/dotclear._no/admin/images/menu/search-b.png b/dotclear._no/admin/images/menu/search-b.png new file mode 100644 index 0000000..0a05024 Binary files /dev/null and b/dotclear._no/admin/images/menu/search-b.png differ diff --git a/dotclear._no/admin/images/menu/search.png b/dotclear._no/admin/images/menu/search.png new file mode 100644 index 0000000..a256d66 Binary files /dev/null and b/dotclear._no/admin/images/menu/search.png differ diff --git a/dotclear._no/admin/images/menu/themes.png b/dotclear._no/admin/images/menu/themes.png new file mode 100644 index 0000000..954840a Binary files /dev/null and b/dotclear._no/admin/images/menu/themes.png differ diff --git a/dotclear._no/admin/images/menu/update.png b/dotclear._no/admin/images/menu/update.png new file mode 100644 index 0000000..0984ace Binary files /dev/null and b/dotclear._no/admin/images/menu/update.png differ diff --git a/dotclear._no/admin/images/menu/user-pref-b.png b/dotclear._no/admin/images/menu/user-pref-b.png new file mode 100644 index 0000000..4813eb4 Binary files /dev/null and b/dotclear._no/admin/images/menu/user-pref-b.png differ diff --git a/dotclear._no/admin/images/menu/user-pref.png b/dotclear._no/admin/images/menu/user-pref.png new file mode 100644 index 0000000..b8db2bb Binary files /dev/null and b/dotclear._no/admin/images/menu/user-pref.png differ diff --git a/dotclear._no/admin/images/menu/users-b.png b/dotclear._no/admin/images/menu/users-b.png new file mode 100644 index 0000000..40cd9cb Binary files /dev/null and b/dotclear._no/admin/images/menu/users-b.png differ diff --git a/dotclear._no/admin/images/menu/users.png b/dotclear._no/admin/images/menu/users.png new file mode 100644 index 0000000..4e1d077 Binary files /dev/null and b/dotclear._no/admin/images/menu/users.png differ diff --git a/dotclear._no/admin/images/menu_off.png b/dotclear._no/admin/images/menu_off.png new file mode 100644 index 0000000..394aea4 Binary files /dev/null and b/dotclear._no/admin/images/menu_off.png differ diff --git a/dotclear._no/admin/images/menu_on.png b/dotclear._no/admin/images/menu_on.png new file mode 100644 index 0000000..698746f Binary files /dev/null and b/dotclear._no/admin/images/menu_on.png differ diff --git a/dotclear._no/admin/images/minus-theme.png b/dotclear._no/admin/images/minus-theme.png new file mode 100644 index 0000000..d0d8b7c Binary files /dev/null and b/dotclear._no/admin/images/minus-theme.png differ diff --git a/dotclear._no/admin/images/minus.png b/dotclear._no/admin/images/minus.png new file mode 100644 index 0000000..5baa0f3 Binary files /dev/null and b/dotclear._no/admin/images/minus.png differ diff --git a/dotclear._no/admin/images/module.png b/dotclear._no/admin/images/module.png new file mode 100644 index 0000000..114598b Binary files /dev/null and b/dotclear._no/admin/images/module.png differ diff --git a/dotclear._no/admin/images/noscreenshot.png b/dotclear._no/admin/images/noscreenshot.png new file mode 100644 index 0000000..93ce0a0 Binary files /dev/null and b/dotclear._no/admin/images/noscreenshot.png differ diff --git a/dotclear._no/admin/images/outgoing-blue.png b/dotclear._no/admin/images/outgoing-blue.png new file mode 100644 index 0000000..7b98d41 Binary files /dev/null and b/dotclear._no/admin/images/outgoing-blue.png differ diff --git a/dotclear._no/admin/images/outgoing-link.svg b/dotclear._no/admin/images/outgoing-link.svg new file mode 100644 index 0000000..0d8a882 --- /dev/null +++ b/dotclear._no/admin/images/outgoing-link.svg @@ -0,0 +1,3 @@ + + + diff --git a/dotclear._no/admin/images/outgoing.png b/dotclear._no/admin/images/outgoing.png new file mode 100644 index 0000000..c80147c Binary files /dev/null and b/dotclear._no/admin/images/outgoing.png differ diff --git a/dotclear._no/admin/images/page_help.png b/dotclear._no/admin/images/page_help.png new file mode 100644 index 0000000..6c6ca03 Binary files /dev/null and b/dotclear._no/admin/images/page_help.png differ diff --git a/dotclear._no/admin/images/pagination/first.png b/dotclear._no/admin/images/pagination/first.png new file mode 100644 index 0000000..32f38b6 Binary files /dev/null and b/dotclear._no/admin/images/pagination/first.png differ diff --git a/dotclear._no/admin/images/pagination/last.png b/dotclear._no/admin/images/pagination/last.png new file mode 100644 index 0000000..61239e9 Binary files /dev/null and b/dotclear._no/admin/images/pagination/last.png differ diff --git a/dotclear._no/admin/images/pagination/next.png b/dotclear._no/admin/images/pagination/next.png new file mode 100644 index 0000000..5010c19 Binary files /dev/null and b/dotclear._no/admin/images/pagination/next.png differ diff --git a/dotclear._no/admin/images/pagination/no-first.png b/dotclear._no/admin/images/pagination/no-first.png new file mode 100644 index 0000000..73684cd Binary files /dev/null and b/dotclear._no/admin/images/pagination/no-first.png differ diff --git a/dotclear._no/admin/images/pagination/no-last.png b/dotclear._no/admin/images/pagination/no-last.png new file mode 100644 index 0000000..aa36ccd Binary files /dev/null and b/dotclear._no/admin/images/pagination/no-last.png differ diff --git a/dotclear._no/admin/images/pagination/no-next.png b/dotclear._no/admin/images/pagination/no-next.png new file mode 100644 index 0000000..d25910a Binary files /dev/null and b/dotclear._no/admin/images/pagination/no-next.png differ diff --git a/dotclear._no/admin/images/pagination/no-previous.png b/dotclear._no/admin/images/pagination/no-previous.png new file mode 100644 index 0000000..d6e9b44 Binary files /dev/null and b/dotclear._no/admin/images/pagination/no-previous.png differ diff --git a/dotclear._no/admin/images/pagination/previous.png b/dotclear._no/admin/images/pagination/previous.png new file mode 100644 index 0000000..e76f322 Binary files /dev/null and b/dotclear._no/admin/images/pagination/previous.png differ diff --git a/dotclear._no/admin/images/palette-traviata.png b/dotclear._no/admin/images/palette-traviata.png new file mode 100644 index 0000000..7ce5664 Binary files /dev/null and b/dotclear._no/admin/images/palette-traviata.png differ diff --git a/dotclear._no/admin/images/picker.png b/dotclear._no/admin/images/picker.png new file mode 100644 index 0000000..0d397c7 Binary files /dev/null and b/dotclear._no/admin/images/picker.png differ diff --git a/dotclear._no/admin/images/plus-theme.png b/dotclear._no/admin/images/plus-theme.png new file mode 100644 index 0000000..06b508f Binary files /dev/null and b/dotclear._no/admin/images/plus-theme.png differ diff --git a/dotclear._no/admin/images/plus.png b/dotclear._no/admin/images/plus.png new file mode 100644 index 0000000..e821c48 Binary files /dev/null and b/dotclear._no/admin/images/plus.png differ diff --git a/dotclear._no/admin/images/scheduled.png b/dotclear._no/admin/images/scheduled.png new file mode 100644 index 0000000..91cc3e0 Binary files /dev/null and b/dotclear._no/admin/images/scheduled.png differ diff --git a/dotclear._no/admin/images/selected.png b/dotclear._no/admin/images/selected.png new file mode 100644 index 0000000..568cdef Binary files /dev/null and b/dotclear._no/admin/images/selected.png differ diff --git a/dotclear._no/admin/images/superadmin.png b/dotclear._no/admin/images/superadmin.png new file mode 100644 index 0000000..1b3e745 Binary files /dev/null and b/dotclear._no/admin/images/superadmin.png differ diff --git a/dotclear._no/admin/images/trackbacks.png b/dotclear._no/admin/images/trackbacks.png new file mode 100644 index 0000000..c39fb9b Binary files /dev/null and b/dotclear._no/admin/images/trackbacks.png differ diff --git a/dotclear._no/admin/images/trash.png b/dotclear._no/admin/images/trash.png new file mode 100644 index 0000000..79132ce Binary files /dev/null and b/dotclear._no/admin/images/trash.png differ diff --git a/dotclear._no/admin/images/up.png b/dotclear._no/admin/images/up.png new file mode 100644 index 0000000..436193d Binary files /dev/null and b/dotclear._no/admin/images/up.png differ diff --git a/dotclear._no/admin/index.php b/dotclear._no/admin/index.php new file mode 100644 index 0000000..e234cbe --- /dev/null +++ b/dotclear._no/admin/index.php @@ -0,0 +1,424 @@ +setUserDefaultBlog($core->auth->userID(), $core->blog->id); + $core->adminurl->redirect("admin.home"); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } +} + +dcPage::check('usage,contentadmin', true); + +if ($core->plugins->disableDepModules($core->adminurl->get('admin.home', []))) { + exit; +} + +# Logout +if (!empty($_GET['logout'])) { + $core->session->destroy(); + if (isset($_COOKIE['dc_admin'])) { + unset($_COOKIE['dc_admin']); + setcookie('dc_admin', false, -600, '', '', DC_ADMIN_SSL); + } + $core->adminurl->redirect("admin.auth"); + exit; +} + +# Plugin install +$plugins_install = $core->plugins->installModules(); + +# Check dashboard module prefs +$ws = $core->auth->user_prefs->addWorkspace('dashboard'); +if (!$core->auth->user_prefs->dashboard->prefExists('doclinks')) { + if (!$core->auth->user_prefs->dashboard->prefExists('doclinks', true)) { + $core->auth->user_prefs->dashboard->put('doclinks', true, 'boolean', '', null, true); + } + $core->auth->user_prefs->dashboard->put('doclinks', true, 'boolean'); +} +if (!$core->auth->user_prefs->dashboard->prefExists('dcnews')) { + if (!$core->auth->user_prefs->dashboard->prefExists('dcnews', true)) { + $core->auth->user_prefs->dashboard->put('dcnews', true, 'boolean', '', null, true); + } + $core->auth->user_prefs->dashboard->put('dcnews', true, 'boolean'); +} +if (!$core->auth->user_prefs->dashboard->prefExists('quickentry')) { + if (!$core->auth->user_prefs->dashboard->prefExists('quickentry', true)) { + $core->auth->user_prefs->dashboard->put('quickentry', false, 'boolean', '', null, true); + } + $core->auth->user_prefs->dashboard->put('quickentry', false, 'boolean'); +} +if (!$core->auth->user_prefs->dashboard->prefExists('nodcupdate')) { + if (!$core->auth->user_prefs->dashboard->prefExists('nodcupdate', true)) { + $core->auth->user_prefs->dashboard->put('nodcupdate', false, 'boolean', '', null, true); + } + $core->auth->user_prefs->dashboard->put('nodcupdate', false, 'boolean'); +} + +// Handle folded/unfolded sections in admin from user preferences +$ws = $core->auth->user_prefs->addWorkspace('toggles'); +if (!$core->auth->user_prefs->toggles->prefExists('unfolded_sections')) { + $core->auth->user_prefs->toggles->put('unfolded_sections', '', 'string', 'Folded sections in admin', null, true); +} + +# Dashboard icons +$__dashboard_icons = new ArrayObject(); + +$favs = $core->favs->getUserFavorites(); +$core->favs->appendDashboardIcons($__dashboard_icons); + +# Check plugins and themes update from repository +$checkStoreUpdate = function ($mod, $url, $img, $icon) { + $repo = new dcStore($mod, $url); + $upd = $repo->get(true); + if (!empty($upd)) { + $icon[0] .= '
    ' . sprintf(__('An update is available', '%s updates are available.', count($upd)), count($upd)); + $icon[1] .= '#update'; + $icon[2] = 'images/menu/' . $img . '-b-update.png'; + } +}; +if (isset($__dashboard_icons['plugins'])) { + $checkStoreUpdate($core->plugins, $core->blog->settings->system->store_plugin_url, 'plugins', $__dashboard_icons['plugins']); +} +if (isset($__dashboard_icons['blog_theme'])) { + $themes = new dcThemes($core); + $themes->loadModules($core->blog->themes_path, null); + $checkStoreUpdate($themes, $core->blog->settings->system->store_theme_url, 'blog-theme', $__dashboard_icons['blog_theme']); +} + +# Latest news for dashboard +$__dashboard_items = new ArrayObject([new ArrayObject(), new ArrayObject()]); + +$dashboardItem = 0; + +# Documentation links +if ($core->auth->user_prefs->dashboard->doclinks) { + if (!empty($__resources['doc'])) { + $doc_links = '

    ' . __('Documentation and support') . '

      '; + + foreach ($__resources['doc'] as $k => $v) { + $doc_links .= '
    • ' . $k . + '
    • '; + } + + $doc_links .= '
    '; + $__dashboard_items[$dashboardItem][] = $doc_links; + $dashboardItem++; + } +} + +$core->callBehavior('adminDashboardItems', $core, $__dashboard_items); + +# Dashboard content +$__dashboard_contents = new ArrayObject([new ArrayObject, new ArrayObject]); +$core->callBehavior('adminDashboardContents', $core, $__dashboard_contents); + +# Editor stuff +$admin_post_behavior = ''; +if ($core->auth->user_prefs->dashboard->quickentry) { + if ($core->auth->check('usage,contentadmin', $core->blog->id)) { + $post_format = $core->auth->getOption('post_format'); + $post_editor = $core->auth->getOption('editor'); + if ($post_editor && !empty($post_editor[$post_format])) { + // context is not post because of tags not available + $admin_post_behavior = $core->callBehavior('adminPostEditor', $post_editor[$post_format], 'quickentry', ['#post_content'], $post_format); + } + } +} + +# Dashboard drag'n'drop switch for its elements +$core->auth->user_prefs->addWorkspace('accessibility'); +$dragndrop = ''; +$dragndrop_head = ''; +$dragndrop_msg = [ + 'dragndrop_off' => __('Dashboard area\'s drag and drop is disabled'), + 'dragndrop_on' => __('Dashboard area\'s drag and drop is enabled') +]; +if (!$core->auth->user_prefs->accessibility->nodragdrop) { + $dragndrop_head = dcPage::jsJson('dotclear_dragndrop', $dragndrop_msg); + $dragndrop = + '' . + ''; +} + +/* DISPLAY +-------------------------------------------------------- */ +dcPage::open(__('Dashboard'), + dcPage::jsLoad('js/jquery/jquery-ui.custom.js') . + dcPage::jsLoad('js/jquery/jquery.ui.touch-punch.js') . + dcPage::jsLoad('js/_index.js') . + $dragndrop_head . + $admin_post_behavior . + # --BEHAVIOR-- adminDashboardHeaders + $core->callBehavior('adminDashboardHeaders'), + dcPage::breadcrumb( + [ + __('Dashboard') . ' : ' . html::escapeHTML($core->blog->name) => '' + ], + ['home_link' => false] + ) +); + +if ($core->auth->getInfo('user_default_blog') != $core->blog->id && $core->auth->getBlogCount() > 1) { + echo + '

    1]) . '" class="button">' . __('Make this blog my default blog') . '

    '; +} + +if ($core->blog->status == 0) { + echo '

    ' . __('This blog is offline') . '.

    '; +} elseif ($core->blog->status == -1) { + echo '

    ' . __('This blog is removed') . '.

    '; +} + +if (!defined('DC_ADMIN_URL') || !DC_ADMIN_URL) { + echo + '

    ' . + sprintf(__('%s is not defined, you should edit your configuration file.'), 'DC_ADMIN_URL') . + ' ' . __('See documentation for more information.') . + '

    '; +} + +if (!defined('DC_ADMIN_MAILFROM') || !DC_ADMIN_MAILFROM) { + echo + '

    ' . + sprintf(__('%s is not defined, you should edit your configuration file.'), 'DC_ADMIN_MAILFROM') . + ' ' . __('See documentation for more information.') . + '

    '; +} + +$err = []; + +# Check cache directory +if ($core->auth->isSuperAdmin()) { + if (!is_dir(DC_TPL_CACHE) || !is_writable(DC_TPL_CACHE)) { + $err[] = '

    ' . __("The cache directory does not exist or is not writable. You must create this directory with sufficient rights and affect this location to \"DC_TPL_CACHE\" in inc/config.php file.") . '

    '; + } +} else { + if (!is_dir(DC_TPL_CACHE) || !is_writable(DC_TPL_CACHE)) { + $err[] = '

    ' . __("The cache directory does not exist or is not writable. You should contact your administrator.") . '

    '; + } +} + +# Check public directory +if ($core->auth->isSuperAdmin()) { + if (!is_dir($core->blog->public_path) || !is_writable($core->blog->public_path)) { + $err[] = '

    ' . __("There is no writable directory /public/ at the location set in about:config \"public_path\". You must create this directory with sufficient rights (or change this setting).") . '

    '; + } +} else { + if (!is_dir($core->blog->public_path) || !is_writable($core->blog->public_path)) { + $err[] = '

    ' . __("There is no writable root directory for the media manager. You should contact your administrator.") . '

    '; + } +} + +# Error list +if (count($err) > 0) { + echo '

    ' . __('Error:') . '

    ' . + '
    • ' . implode("
    • ", $err) . '
    '; +} + +# Plugins install messages +if (!empty($plugins_install['success'])) { + echo '
    ' . __('Following plugins have been installed:') . '
      '; + foreach ($plugins_install['success'] as $k => $v) { + echo '
    • ' . $k . '
    • '; + } + echo '
    '; +} +if (!empty($plugins_install['failure'])) { + echo '
    ' . __('Following plugins have not been installed:') . '
      '; + foreach ($plugins_install['failure'] as $k => $v) { + echo '
    • ' . $k . ' (' . $v . ')
    • '; + } + echo '
    '; +} +# Errors modules notifications +if ($core->auth->isSuperAdmin()) { + $list = $core->plugins->getErrors(); + if (!empty($list)) { + echo + '

    ' . __('Errors have occured with following plugins:') . '

    ' . + '
    • ' . implode("
    • \n
    • ", $list) . '
    '; + } +} + +# Get current main orders +$main_order = $core->auth->user_prefs->dashboard->main_order; +$main_order = ($main_order != '' ? explode(',', $main_order) : []); + +# Get current boxes orders +$boxes_order = $core->auth->user_prefs->dashboard->boxes_order; +$boxes_order = ($boxes_order != '' ? explode(',', $boxes_order) : []); + +# Get current boxes items orders +$boxes_items_order = $core->auth->user_prefs->dashboard->boxes_items_order; +$boxes_items_order = ($boxes_items_order != '' ? explode(',', $boxes_items_order) : []); + +# Get current boxes contents orders +$boxes_contents_order = $core->auth->user_prefs->dashboard->boxes_contents_order; +$boxes_contents_order = ($boxes_contents_order != '' ? explode(',', $boxes_contents_order) : []); + +$composeItems = function ($list, $blocks, $flat = false) { + + $ret = []; + $items = []; + + if ($flat) { + $items = $blocks; + } else { + foreach ($blocks as $i) { + foreach ($i as $v) { + $items[] = $v; + } + } + } + + # First loop to find ordered indexes + $order = []; + $index = 0; + foreach ($items as $v) { + if (preg_match('//ms', $v, $match)) { + $id = $match[1]; + $position = array_search($id, $list, true); + if ($position !== false) { + $order[$position] = $index; + } + } + $index++; + } + + # Second loop to combine ordered items + $index = 0; + foreach ($items as $v) { + $position = array_search($index, $order, true); + if ($position !== false) { + $ret[$position] = $v; + } + $index++; + } + # Reorder items on their position (key) + ksort($ret); + + # Third loop to combine unordered items + $index = 0; + foreach ($items as $v) { + $position = array_search($index, $order, true); + if ($position === false) { + $ret[count($ret)] = $v; + } + $index++; + } + + return join('', $ret); +}; + +# Compose dashboard items (doc, …) +$dashboardItems = $composeItems($boxes_items_order, $__dashboard_items); +# Compose dashboard contents (plugin's modules) +$dashboardContents = $composeItems($boxes_contents_order, $__dashboard_contents); + +$__dashboard_boxes = []; +if ($dashboardItems != '') { + $__dashboard_boxes[] = '
    ' . $dashboardItems . '
    '; +} +if ($dashboardContents != '') { + $__dashboard_boxes[] = '
    ' . $dashboardContents . '
    '; +} +$dashboardBoxes = $composeItems($boxes_order, $__dashboard_boxes, true); + +# Compose main area +$__dashboard_main = []; +if (!$core->auth->user_prefs->dashboard->nofavicons) { + # Dashboard icons + $dashboardIcons = '
    '; + foreach ($__dashboard_icons as $i) { + $dashboardIcons .= '

    ' . + '
    ' . $i[0] . '

    '; + } + $dashboardIcons .= '
    '; + $__dashboard_main[] = $dashboardIcons; +} +if ($core->auth->user_prefs->dashboard->quickentry) { + if ($core->auth->check('usage,contentadmin', $core->blog->id)) { + # Getting categories + $categories_combo = dcAdminCombos::getCategoriesCombo( + $core->blog->getCategories([]) + ); + + $dashboardQuickEntry = + '
    ' . + '

    ' . __('Quick post') . sprintf(' › %s', $core->auth->getOption('post_format')) . '

    ' . + '
    ' . + '

    ' . __('New post') . '

    ' . + '

    ' . + form::field('post_title', 20, 255, [ + 'class' => 'maximal', + 'extra_html' => 'required placeholder="' . __('Title') . '"' + ]) . + '

    ' . + '
    ' . + form::textarea('post_content', 50, 10, ['extra_html' => 'required placeholder="' . __('Content') . '"']) . + '
    ' . + '

    ' . + form::combo('cat_id', $categories_combo) . '

    ' . + ($core->auth->check('categories', $core->blog->id) + ? '
    ' . + '

    ' . __('Add a new category') . '

    ' . + '

    ' . + form::field('new_cat_title', 30, 255) . '

    ' . + '

    ' . + form::combo('new_cat_parent', $categories_combo) . + '

    ' . + '

    ' . __('This category will be created when you will save your post.') . '

    ' . + '
    ' + : '') . + '

    ' . + ($core->auth->check('publish', $core->blog->id) + ? '' + : '') . + $core->formNonce() . + form::hidden('post_status', -2) . + form::hidden('post_format', $core->auth->getOption('post_format')) . + form::hidden('post_excerpt', '') . + form::hidden('post_lang', $core->auth->getInfo('user_lang')) . + form::hidden('post_notes', '') . + '

    ' . + '
    ' . + '
    '; + $__dashboard_main[] = $dashboardQuickEntry; + } +} +if ($dashboardBoxes != '') { + $__dashboard_main[] = '
    ' . $dashboardBoxes . '
    '; +} +$dashboardMain = $composeItems($main_order, $__dashboard_main, true); + +echo $dragndrop . '
    ' . $dashboardMain . '
    '; + +dcPage::helpBlock('core_dashboard'); +dcPage::close(); diff --git a/dotclear._no/admin/install/check.php b/dotclear._no/admin/install/check.php new file mode 100644 index 0000000..7833f8f --- /dev/null +++ b/dotclear._no/admin/install/check.php @@ -0,0 +1,73 @@ +syntax() == 'mysql') { + if (version_compare($con->version(), '4.1', '<')) { + $err[] = sprintf(__('MySQL version is %s (4.1 or earlier needed).'), $con->version()); + } else { + $rs = $con->select('SHOW ENGINES'); + $innodb = false; + while ($rs->fetch()) { + if (strtolower($rs->f(0)) == 'innodb' && strtolower($rs->f(1)) != 'disabled' && strtolower($rs->f(1)) != 'no') { + $innodb = true; + break; + } + } + + if (!$innodb) { + $err[] = __('MySQL InnoDB engine is not available.'); + } + } + } elseif ($con->driver() == 'pgsql') { + if (version_compare($con->version(), '8.0', '<')) { + $err[] = sprintf(__('PostgreSQL version is %s (8.0 or earlier needed).'), $con->version()); + } + } + + return count($err) == 0; +} diff --git a/dotclear._no/admin/install/index.php b/dotclear._no/admin/install/index.php new file mode 100644 index 0000000..61c6bad --- /dev/null +++ b/dotclear._no/admin/install/index.php @@ -0,0 +1,421 @@ +' . __('Please set a master key (DC_MASTER_KEY) in configuration file.') . '

    '; +} + +# Check if dotclear is already installed +$schema = dbSchema::init($core->con); +if (in_array($core->prefix . 'post', $schema->getTables())) { + $can_install = false; + $err = '

    ' . __('Dotclear is already installed.') . '

    '; +} + +# Check system capabilites +if (!dcSystemCheck($core->con, $_e)) { + $can_install = false; + $err = '

    ' . __('Dotclear cannot be installed.') . '

    • ' . implode('
    • ', $_e) . '
    '; +} + +# Get information and perform install +$u_email = $u_firstname = $u_name = $u_login = $u_pwd = ''; +$mail_sent = false; +if ($can_install && !empty($_POST)) { + $u_email = !empty($_POST['u_email']) ? $_POST['u_email'] : null; + $u_firstname = !empty($_POST['u_firstname']) ? $_POST['u_firstname'] : null; + $u_name = !empty($_POST['u_name']) ? $_POST['u_name'] : null; + $u_login = !empty($_POST['u_login']) ? $_POST['u_login'] : null; + $u_pwd = !empty($_POST['u_pwd']) ? $_POST['u_pwd'] : null; + $u_pwd2 = !empty($_POST['u_pwd2']) ? $_POST['u_pwd2'] : null; + + try + { + # Check user information + if (empty($u_login)) { + throw new Exception(__('No user ID given')); + } + if (!preg_match('/^[A-Za-z0-9@._-]{2,}$/', $u_login)) { + throw new Exception(__('User ID must contain at least 2 characters using letters, numbers or symbols.')); + } + if ($u_email && !text::isEmail($u_email)) { + throw new Exception(__('Invalid email address')); + } + + if (empty($u_pwd)) { + throw new Exception(__('No password given')); + } + if ($u_pwd != $u_pwd2) { + throw new Exception(__("Passwords don't match")); + } + if (strlen($u_pwd) < 6) { + throw new Exception(__('Password must contain at least 6 characters.')); + } + + # Try to guess timezone + $default_tz = 'Europe/London'; + if (!empty($_POST['u_date']) && function_exists('timezone_open')) { + if (preg_match('/\((.+)\)$/', $_POST['u_date'], $_tz)) { + $_tz = $_tz[1]; + $_tz = @timezone_open($_tz); + if ($_tz instanceof DateTimeZone) { + $_tz = @timezone_name_get($_tz); + + // check if timezone is valid + // date_default_timezone_set throw E_NOTICE and/or E_WARNING if timezone is not valid and return false + if (@date_default_timezone_set($_tz) !== false && $_tz) { + $default_tz = $_tz; + } + } + unset($_tz); + } + } + + # Create schema + $_s = new dbStruct($core->con, $core->prefix); + require dirname(__FILE__) . '/../../inc/dbschema/db-schema.php'; + + $si = new dbStruct($core->con, $core->prefix); + $changes = $si->synchronize($_s); + + # Create user + $cur = $core->con->openCursor($core->prefix . 'user'); + $cur->user_id = $u_login; + $cur->user_super = 1; + $cur->user_pwd = $core->auth->crypt($u_pwd); + $cur->user_name = (string) $u_name; + $cur->user_firstname = (string) $u_firstname; + $cur->user_email = (string) $u_email; + $cur->user_lang = $dlang; + $cur->user_tz = $default_tz; + $cur->user_creadt = date('Y-m-d H:i:s'); + $cur->user_upddt = date('Y-m-d H:i:s'); + $cur->user_options = serialize($core->userDefaults()); + $cur->insert(); + + $core->auth->checkUser($u_login); + + $admin_url = preg_replace('%install/index.php$%', '', $_SERVER['REQUEST_URI']); + $root_url = preg_replace('%/admin/install/index.php$%', '', $_SERVER['REQUEST_URI']); + + # Create blog + $cur = $core->con->openCursor($core->prefix . 'blog'); + $cur->blog_id = 'default'; + $cur->blog_url = http::getHost() . $root_url . '/index.php?'; + $cur->blog_name = __('My first blog'); + $core->addBlog($cur); + $core->blogDefaults($cur->blog_id); + + $blog_settings = new dcSettings($core, 'default'); + $blog_settings->addNamespace('system'); + $blog_settings->system->put('blog_timezone', $default_tz); + $blog_settings->system->put('lang', $dlang); + $blog_settings->system->put('public_url', $root_url . '/public'); + $blog_settings->system->put('themes_url', $root_url . '/themes'); + + # date and time formats + $formatDate = __('%A, %B %e %Y'); + $date_formats = ['%Y-%m-%d', '%m/%d/%Y', '%d/%m/%Y', '%Y/%m/%d', '%d.%m.%Y', '%b %e %Y', '%e %b %Y', '%Y %b %e', + '%a, %Y-%m-%d', '%a, %m/%d/%Y', '%a, %d/%m/%Y', '%a, %Y/%m/%d', '%B %e, %Y', '%e %B, %Y', '%Y, %B %e', '%e. %B %Y', + '%A, %B %e, %Y', '%A, %e %B, %Y', '%A, %Y, %B %e', '%A, %Y, %B %e', '%A, %e. %B %Y']; + $time_formats = ['%H:%M', '%I:%M', '%l:%M', '%Hh%M', '%Ih%M', '%lh%M']; + if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') { + $formatDate = preg_replace('#(?system->put('date_format', $formatDate); + $blog_settings->system->put('date_formats', $date_formats, 'array', 'Date formats examples', true, true); + $blog_settings->system->put('time_formats', $time_formats, 'array', 'Time formats examples', true, true); + + # Add repository URL for themes and plugins + $blog_settings->system->put('store_plugin_url', 'https://update.dotaddict.org/dc2/plugins.xml', 'string', 'Plugins XML feed location', true, true); + $blog_settings->system->put('store_theme_url', 'https://update.dotaddict.org/dc2/themes.xml', 'string', 'Themes XML feed location', true, true); + + # CSP directive (admin part) + + /* SQlite Clearbricks driver does not allow using single quote at beginning or end of a field value + so we have to use neutral values (localhost and 127.0.0.1) for some CSP directives + */ + $csp_prefix = $core->con->driver() == 'sqlite' ? 'localhost ' : ''; // Hack for SQlite Clearbricks driver + $csp_suffix = $core->con->driver() == 'sqlite' ? ' 127.0.0.1' : ''; // Hack for SQlite Clearbricks driver + + $blog_settings->system->put('csp_admin_on', true, 'boolean', 'Send CSP header (admin)', true, true); + $blog_settings->system->put('csp_admin_report_only', false, 'boolean', 'CSP Report only violations (admin)', true, true); + $blog_settings->system->put('csp_admin_default', + $csp_prefix . "'self'" . $csp_suffix, 'string', 'CSP default-src directive', true, true); + $blog_settings->system->put('csp_admin_script', + $csp_prefix . "'self' 'unsafe-eval'" . $csp_suffix, 'string', 'CSP script-src directive', true, true); + $blog_settings->system->put('csp_admin_style', + $csp_prefix . "'self' 'unsafe-inline'" . $csp_suffix, 'string', 'CSP style-src directive', true, true); + $blog_settings->system->put('csp_admin_img', + $csp_prefix . "'self' data: https://media.dotaddict.org blob:", 'string', 'CSP img-src directive', true, true); + + # Add Dotclear version + $cur = $core->con->openCursor($core->prefix . 'version'); + $cur->module = 'core'; + $cur->version = (string) DC_VERSION; + $cur->insert(); + + # Create first post + $core->setBlog('default'); + + $cur = $core->con->openCursor($core->prefix . 'post'); + $cur->user_id = $u_login; + $cur->post_format = 'xhtml'; + $cur->post_lang = $dlang; + $cur->post_title = __('Welcome to Dotclear!'); + $cur->post_content = '

    ' . __('This is your first entry. When you\'re ready ' . + 'to blog, log in to edit or delete it.') . '

    '; + $cur->post_content_xhtml = $cur->post_content; + $cur->post_status = 1; + $cur->post_open_comment = 1; + $cur->post_open_tb = 0; + $post_id = $core->blog->addPost($cur); + + # Add a comment to it + $cur = $core->con->openCursor($core->prefix . 'comment'); + $cur->post_id = $post_id; + $cur->comment_tz = $default_tz; + $cur->comment_author = __('Dotclear Team'); + $cur->comment_email = 'contact@dotclear.net'; + $cur->comment_site = 'https://dotclear.org/'; + $cur->comment_content = __("

    This is a comment.

    \n

    To delete it, log in and " . + "view your blog's comments. Then you might remove or edit it.

    "); + $core->blog->addComment($cur); + + # Plugins initialization + define('DC_CONTEXT_ADMIN', true); + $core->plugins->loadModules(DC_PLUGINS_ROOT); + $plugins_install = $core->plugins->installModules(); + + # Add dashboard module options + $core->auth->user_prefs->addWorkspace('dashboard'); + $core->auth->user_prefs->dashboard->put('doclinks', true, 'boolean', '', null, true); + $core->auth->user_prefs->dashboard->put('dcnews', true, 'boolean', '', null, true); + $core->auth->user_prefs->dashboard->put('quickentry', true, 'boolean', '', null, true); + $core->auth->user_prefs->dashboard->put('nodcupdate', false, 'boolean', '', null, true); + + # Add accessibility options + $core->auth->user_prefs->addWorkspace('accessibility'); + $core->auth->user_prefs->accessibility->put('nodragdrop', false, 'boolean', '', null, true); + + # Add user interface options + $core->auth->user_prefs->addWorkspace('interface'); + $core->auth->user_prefs->interface->put('enhanceduploader', true, 'boolean', '', null, true); + + # Add default favorites + $core->favs = new dcFavorites($core); + $init_favs = ['posts', 'new_post', 'newpage', 'comments', 'categories', 'media', 'blog_theme', 'widgets', 'simpleMenu', 'prefs', 'help']; + $core->favs->setFavoriteIDs($init_favs, true); + + $step = 1; + } catch (Exception $e) { + $err = $e->getMessage(); + } +} + +if (!isset($step)) { + $step = 0; +} +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+ + +?> + + + + + + + + + + <?php echo __('Dotclear Install'); ?> + + + + + + + + + + + + +
    +' . __('Dotclear installation') . '' . + '
    '; + +if (!is_writable(DC_TPL_CACHE)) { + echo ''; +} + +if ($can_install && !empty($err)) { + echo ''; +} + +if (!empty($_GET['wiz'])) { + echo ''; +} + +if ($can_install && $step == 0) { + echo + '

    ' . __('User information') . '

    ' . + + '

    ' . __('Please provide the following information needed to create the first user.') . '

    ' . + + '
    ' . + '
    ' . __('User information') . '' . + '

    ' . + form::field('u_firstname', 30, 255, [ + 'default' => html::escapeHTML($u_firstname), + 'autocomplete' => 'given-name' + ]) . + '

    ' . + '

    ' . + form::field('u_name', 30, 255, [ + 'default' => html::escapeHTML($u_name), + 'autocomplete' => 'family-name' + ]) . + '

    ' . + '

    ' . + form::email('u_email', [ + 'size' => 30, + 'default' => html::escapeHTML($u_email), + 'autocomplete' => 'email' + ]) . + '

    ' . + '
    ' . + + '
    ' . __('Username and password') . '' . + '

    ' . + '
    ' . + '

    ' . + '' . + form::password('u_pwd', 30, 255, [ + 'extra_html' => 'data-indicator="pwindicator" required placeholder="' . __('Password') . '"', + 'autocomplete' => 'new-password' + ]) . + '

    ' . + '
    ' . + '
    ' . + '

    ' . + '
    ' . + '
    ' . + '

    ' . + '
    ' . + + '

    ' . + '
    '; +} elseif ($can_install && $step == 1) { + # Plugins install messages + $plugins_install_result = ''; + if (!empty($plugins_install['success'])) { + $plugins_install_result .= '
    ' . __('Following plugins have been installed:') . '
      '; + foreach ($plugins_install['success'] as $k => $v) { + $plugins_install_result .= '
    • ' . $k . '
    • '; + } + $plugins_install_result .= '
    '; + } + if (!empty($plugins_install['failure'])) { + $plugins_install_result .= '
    ' . __('Following plugins have not been installed:') . '
      '; + foreach ($plugins_install['failure'] as $k => $v) { + $plugins_install_result .= '
    • ' . $k . ' (' . $v . ')
    • '; + } + $plugins_install_result .= '
    '; + } + + echo + '

    ' . __('All done!') . '

    ' . + + $plugins_install_result . + + '' . + + '

    ' . __('Your account') . '

    ' . + '
      ' . + '
    • ' . __('Username:') . ' ' . html::escapeHTML($u_login) . '
    • ' . + '
    • ' . __('Password:') . ' ' . html::escapeHTML($u_pwd) . '
    • ' . + '
    ' . + + '

    ' . __('Your blog') . '

    ' . + '
      ' . + '
    • ' . __('Blog address:') . ' ' . html::escapeHTML(http::getHost() . $root_url) . '/index.php?
    • ' . + '
    • ' . __('Administration interface:') . ' ' . html::escapeHTML(http::getHost() . $admin_url) . '
    • ' . + '
    ' . + + '
    ' . + '

    ' . + form::hidden(['user_id'], html::escapeHTML($u_login)) . + form::hidden(['user_pwd'], html::escapeHTML($u_pwd)) . + '

    ' . + '
    '; +} elseif (!$can_install) { + echo '

    ' . __('Installation can not be completed') . '

    ' . + '' . + '

    ' . __('For the said reasons, Dotclear can not be installed. ' . + 'Please refer to ' . + 'the documentation to learn how to correct the problem.') . '

    '; +} +?> +
    +
    + + diff --git a/dotclear._no/admin/install/wizard.php b/dotclear._no/admin/install/wizard.php new file mode 100644 index 0000000..82ff26e --- /dev/null +++ b/dotclear._no/admin/install/wizard.php @@ -0,0 +1,231 @@ +' . sprintf(__('Path %s is not writable.'), path::real(dirname(DC_RC_PATH))) . '

    ' . + '

    ' . __('Dotclear installation wizard could not create configuration file for you. ' . + 'You must change folder right or create the config.php ' . + 'file manually, please refer to ' . + '' . + 'the documentation to learn how to do this.') . '

    '; +} + +$DBDRIVER = !empty($_POST['DBDRIVER']) ? $_POST['DBDRIVER'] : (function_exists('mysqli_connect') ? 'mysqli' : 'mysql'); +$DBHOST = !empty($_POST['DBHOST']) ? $_POST['DBHOST'] : ''; +$DBNAME = !empty($_POST['DBNAME']) ? $_POST['DBNAME'] : ''; +$DBUSER = !empty($_POST['DBUSER']) ? $_POST['DBUSER'] : ''; +$DBPASSWORD = !empty($_POST['DBPASSWORD']) ? $_POST['DBPASSWORD'] : ''; +$DBPREFIX = !empty($_POST['DBPREFIX']) ? $_POST['DBPREFIX'] : 'dc_'; +$ADMINMAILFROM = !empty($_POST['ADMINMAILFROM']) ? $_POST['ADMINMAILFROM'] : ''; + +if (!empty($_POST)) { + try + { + if ($DBDRIVER == 'sqlite') { + if (strpos($DBNAME, '/') === false) { + $sqlite_db_directory = dirname(DC_RC_PATH) . '/../db/'; + files::makeDir($sqlite_db_directory, true); + + # Can we write sqlite_db_directory ? + if (!is_writable($sqlite_db_directory)) { + throw new Exception(sprintf(__('Cannot write "%s" directory.'), path::real($sqlite_db_directory, false))); + } + $DBNAME = $sqlite_db_directory . $DBNAME; + } + } + + # Tries to connect to database + try { + $con = dbLayer::init($DBDRIVER, $DBHOST, $DBNAME, $DBUSER, $DBPASSWORD); + } catch (Exception $e) { + throw new Exception('

    ' . __($e->getMessage()) . '

    '); + } + + # Checks system capabilites + require dirname(__FILE__) . '/check.php'; + if (!dcSystemCheck($con, $_e)) { + $can_install = false; + throw new Exception('

    ' . __('Dotclear cannot be installed.') . '

    • ' . implode('
    • ', $_e) . '
    '); + } + + # Check if dotclear is already installed + $schema = dbSchema::init($con); + if (in_array($DBPREFIX . 'version', $schema->getTables())) { + throw new Exception(__('Dotclear is already installed.')); + } + # Check master email + if (!text::isEmail($ADMINMAILFROM)) { + throw new Exception(__('Master email is not valid.')); + } + + # Does config.php.in exist? + $config_in = dirname(__FILE__) . '/../../inc/config.php.in'; + if (!is_file($config_in)) { + throw new Exception(sprintf(__('File %s does not exist.'), $config_in)); + } + + # Can we write config.php + if (!is_writable(dirname(DC_RC_PATH))) { + throw new Exception(sprintf(__('Cannot write %s file.'), DC_RC_PATH)); + } + + # Creates config.php file + $full_conf = file_get_contents($config_in); + + writeConfigValue('DC_DBDRIVER', $DBDRIVER, $full_conf); + writeConfigValue('DC_DBHOST', $DBHOST, $full_conf); + writeConfigValue('DC_DBUSER', $DBUSER, $full_conf); + writeConfigValue('DC_DBPASSWORD', $DBPASSWORD, $full_conf); + writeConfigValue('DC_DBNAME', $DBNAME, $full_conf); + writeConfigValue('DC_DBPREFIX', $DBPREFIX, $full_conf); + + $admin_url = preg_replace('%install/wizard.php$%', '', $_SERVER['REQUEST_URI']); + writeConfigValue('DC_ADMIN_URL', http::getHost() . $admin_url, $full_conf); + $admin_email = !empty($ADMINMAILFROM) ? $ADMINMAILFROM : 'dotclear@' . $_SERVER['HTTP_HOST']; + writeConfigValue('DC_ADMIN_MAILFROM', $admin_email, $full_conf); + writeConfigValue('DC_MASTER_KEY', md5(uniqid()), $full_conf); + + $fp = @fopen(DC_RC_PATH, 'wb'); + if ($fp === false) { + throw new Exception(sprintf(__('Cannot write %s file.'), DC_RC_PATH)); + } + fwrite($fp, $full_conf); + fclose($fp); + chmod(DC_RC_PATH, 0666); + + $con->close(); + http::redirect('index.php?wiz=1'); + } catch (Exception $e) { + $err = $e->getMessage(); + } +} + +function writeConfigValue($name, $val, &$str) +{ + $val = str_replace("'", "\'", $val); + $str = preg_replace('/(\'' . $name . '\')(.*?)$/ms', '$1,\'' . $val . '\');', $str); +} + +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+ + +?> + + + + + + + + + + <?php echo __('Dotclear installation wizard'); ?> + + + + +
    +' . __('Dotclear installation wizard') . '' . + '
    '; + +if (!empty($err)) { + echo ''; +} else { + echo '

    ' . __('Welcome') . '

    ' . + '

    ' . __('To complete your Dotclear installation and start writing on your blog, ' . + 'we just need to know how to access your database and who you are. ' . + 'Just fill this two steps wizard with this information and we will be done.') . '

    ' . + '

    ' . __('Attention:') . ' ' . + __('this wizard may not function on every host. If it does not work for you, ' . + 'please refer to ' . + 'the documentation to learn how to create the config.php ' . + 'file manually.') . '

    '; +} + +echo +'

    ' . __('System information') . '

    ' . + +'

    ' . __('Please provide the following information needed to create your configuration file.') . '

    ' . + +'
    ' . +'

    ' . +form::combo('DBDRIVER', [ + __('MySQL (deprecated)') => 'mysql', + __('MySQLi') => 'mysqli', + __('MySQLi (full UTF-8)') => 'mysqlimb4', + __('PostgreSQL') => 'pgsql', + __('SQLite') => 'sqlite'], + ['default' => $DBDRIVER, 'extra_html' => 'required placeholder="' . __('Driver') . '"']) . '

    ' . +'

    ' . +form::field('DBHOST', 30, 255, html::escapeHTML($DBHOST)) . '

    ' . +'

    ' . +form::field('DBNAME', 30, 255, html::escapeHTML($DBNAME)) . '

    ' . +'

    ' . +form::field('DBUSER', 30, 255, html::escapeHTML($DBUSER)) . '

    ' . +'

    ' . +form::password('DBPASSWORD', 30, 255) . '

    ' . +'

    ' . +form::field('DBPREFIX', 30, 255, [ + 'default' => html::escapeHTML($DBPREFIX), + 'extra_html' => 'required placeholder="' . __('Prefix') . '"' +]) . +'

    ' . +'

    ' . +form::email('ADMINMAILFROM', [ + 'size' => 30, + 'default' => html::escapeHTML($ADMINMAILFROM), + 'autocomplete' => 'email' +]) . +'

    ' . + +'

    ' . + '
    '; +?> +
    +
    + + diff --git a/dotclear._no/admin/js/_auth.js b/dotclear._no/admin/js/_auth.js new file mode 100644 index 0000000..300bf05 --- /dev/null +++ b/dotclear._no/admin/js/_auth.js @@ -0,0 +1,4 @@ +'use strict';$(window).on('load',function(){let uid=$('input[name=user_id]');let upw=$('input[name=user_pwd]');uid.trigger('focus');if(upw.length==0){return;} +uid.keypress(evt=>{if(evt.which==13&&upw.val()==''){upw.trigger('focus');return false;} +return true;});$.cookie('dc_admin_test_cookie',true);if($.cookie('dc_admin_test_cookie')){$('#cookie_help').hide();$.cookie('dc_admin_test_cookie','',{'expires':-1});}else{$('#cookie_help').show();} +$('#issue #more').toggleWithLegend($('#issue').children().not('#more'));}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_blog_pref.js b/dotclear._no/admin/js/_blog_pref.js new file mode 100644 index 0000000..4e3888d --- /dev/null +++ b/dotclear._no/admin/js/_blog_pref.js @@ -0,0 +1,5 @@ +'use strict';Object.assign(dotclear.msg,getData('blog_pref'));$(function(){const blog_url=$('#blog_url');if(blog_url.length>0&&!blog_url.is(':hidden')){const checkQueryString=function(){const url=blog_url[0].value;const scan=$('#url_scan')[0].value;let msg='';if(/.*[^\/]$/.exec(url)&&scan=='path_info'){msg=dotclear.msg.warning_path_info;}else if(/.*[^\?]$/.exec(url)&&scan=='query_string'){msg=dotclear.msg.warning_query_string;} +$('p#urlwarning').remove();if(msg!=''){blog_url.parents('p').after(`

    ${msg}

    `);}};checkQueryString();blog_url.on('focusout',checkQueryString);$('body').on('change','#url_scan',checkQueryString);} +$('#date_format_select,#time_format_select').on('change',function(){if($(this).prop('value')==''){return;} +$('#'+$(this).attr('id').replace('_select','')).prop('value',$(this).prop('value'));$(this).parent().next('.chosen').html($(this).find(':selected').prop('label'));});$('#static_home_url_selector').on('click',function(e){window.open('popup_posts.php?plugin_id=admin.blog_pref&type=page','dc_popup','alwaysRaised=yes,dependent=yes,toolbar=yes,height=500,width=760,'+'menubar=no,resizable=yes,scrollbars=yes,status=no');e.preventDefault();return false;});if(typeof jsToolBar!=='undefined'&&$.isFunction(jsToolBar)){$('#blog_desc').each(function(){let tbWidgetText=new jsToolBar(this);tbWidgetText.context='blog_desc';tbWidgetText.draw('xhtml');});} +$('#standard-pref h3').toggleWithLegend($('#standard-pref').children().not('h3'),{legend_click:true,hide:false});$('#advanced-pref h3').toggleWithLegend($('#advanced-pref').children().not('h3'),{legend_click:true,user_pref:'dcx_blog_pref_adv',});$('#plugins-pref h3').toggleWithLegend($('#plugins-pref').children().not('h3'),{legend_click:true,user_pref:'dcx_blog_pref_plg',});}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_blog_pref_popup_posts.js b/dotclear._no/admin/js/_blog_pref_popup_posts.js new file mode 100644 index 0000000..774d228 --- /dev/null +++ b/dotclear._no/admin/js/_blog_pref_popup_posts.js @@ -0,0 +1,3 @@ +'use strict';Object.assign(dotclear,getData('admin.blog_pref'));$(function(){$('#link-insert-cancel').on('click',function(){window.close();});$('#form-entries tr>td.maximal>a').on('click',function(){function stripBaseURL(url){if(dotclear.base_url!=''){var pos=url.indexOf(dotclear.base_url);if(pos==0){url=url.substr(dotclear.base_url.length);}} +return url;} +const main=window.opener;const title=stripBaseURL($(this).attr('title'));const next=title.indexOf('/');const href=next!==-1?title.substring(next+1):title;main.$('#static_home_url').prop('value',href);window.close();});}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_blog_theme.js b/dotclear._no/admin/js/_blog_theme.js new file mode 100644 index 0000000..3df179c --- /dev/null +++ b/dotclear._no/admin/js/_blog_theme.js @@ -0,0 +1,4 @@ +'use strict';$(function(){$('.module-sshot').not('.current-theme .module-sshot').each(function(){const bar=$('
    ').addClass('bloc-toggler');$(this).after($(bar).toggleWithLegend($(this).parent().children('.toggle-bloc'),{img_on_txt:dotclear.img_plus_theme_txt,img_on_alt:dotclear.img_plus_theme_alt,img_off_txt:dotclear.img_minus_theme_txt,img_off_alt:dotclear.img_minus_theme_alt,legend_click:true}));$(this).children('img').on('click',function(){$(this).parent().parent().children('.bloc-toggler').trigger('click');});});$('div.modules-search form input[type=submit]').on('click',function(){const mlen=$('input[name=m_search]',$(this).parent()).val();if(mlen.length>2){return true;}else{return false;}});$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this);});$('.modules-form-actions').each(function(){const rxActionType=/^[^\[]+/;const rxActionValue=/([^\[]+)\]$/;const checkboxes=$(this).find('input[type=checkbox]');$('input[type=submit]',this).on('click',function(){const keyword=$(this).attr('name');if(!keyword){return true;} +const maction=keyword.match(rxActionType);const action=maction[0];const mvalues=keyword.match(rxActionValue);if(!mvalues){let checked=false;if(checkboxes.length>0){$(checkboxes).each(function(){if(this.checked){checked=true;}});if(!checked){return false;}} +if(action=='delete'){return window.confirm(dotclear.msg.confirm_delete_themes);}}else{const module=mvalues[1];if(action=='delete'){return window.confirm(dotclear.msg.confirm_delete_theme.replace('%s',module));}} +return true;});});}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_blogs.js b/dotclear._no/admin/js/_blogs.js new file mode 100644 index 0000000..21018eb --- /dev/null +++ b/dotclear._no/admin/js/_blogs.js @@ -0,0 +1 @@ +'use strict';$(function(){$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this,undefined,'#form-blogs td input[type=checkbox]','#form-blogs #do-action');});$('#form-blogs td input[type=checkbox]').enableShiftClick();dotclear.condSubmit('#form-blogs td input[type=checkbox]','#form-blogs #do-action');dotclear.responsiveCellHeaders(document.querySelector('#form-blogs table'),'#form-blogs table',1);$('#form-blogs').on('submit',function(){const action=$(this).find('select[name="action"]').val();if(action=='delete'){return window.confirm(dotclear.msg.confirm_delete_blog.replace('%s',$('input[name="blogs[]"]:checked').length));}});}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_blogs_actions.js b/dotclear._no/admin/js/_blogs_actions.js new file mode 100644 index 0000000..da23f4c --- /dev/null +++ b/dotclear._no/admin/js/_blogs_actions.js @@ -0,0 +1 @@ +'use strict';$(function(){dotclear.condSubmit('table.blogs-list td input[type=checkbox]','input[type=submit]');}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_categories.js b/dotclear._no/admin/js/_categories.js new file mode 100644 index 0000000..bcc05e4 --- /dev/null +++ b/dotclear._no/admin/js/_categories.js @@ -0,0 +1,2 @@ +'use strict';$(function(){if($.fn.nestedSortable!==undefined){$('#categories ul li').css('cursor','move');$('#save-set-order').prop('disabled',true).addClass('disabled');$('#categories ul').nestedSortable({listType:'ul',items:'li',placeholder:'placeholder',update:function(){$('#categories_order').attr('value',JSON.stringify($('#categories ul').nestedSortable('toArray')));$('#save-set-order').prop('disabled',false).removeClass('disabled');}});} +$('input[name^="delete"]').on('click',function(){return window.confirm(dotclear.msg.confirm_delete_category.replace('%s',$(this).parents('li').first().find('.cat-title label a').text()));});$('input[name="reset"]').on('click',function(){return window.confirm(dotclear.msg.confirm_reorder_categories);});}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_category.js b/dotclear._no/admin/js/_category.js new file mode 100644 index 0000000..c9dfa95 --- /dev/null +++ b/dotclear._no/admin/js/_category.js @@ -0,0 +1 @@ +'use strict';$(function(){dotclear.hideLockable();if(typeof jsToolBar!=='undefined'&&$.isFunction(jsToolBar)){const tbCategory=new jsToolBar(document.getElementById('cat_desc'));tbCategory.draw('xhtml');}}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_charte.js b/dotclear._no/admin/js/_charte.js new file mode 100644 index 0000000..aa35ec3 --- /dev/null +++ b/dotclear._no/admin/js/_charte.js @@ -0,0 +1 @@ +'use strict';$(function(){$.pageTabs('two-boxes');$('#pageslist').sortable({'cursor':'move'});$('#pageslist tr').on('hover',function(){$(this).css({'cursor':'move'});},function(){$(this).css({'cursor':'auto'});});$('#pageslist tr td input.position').hide();$('#pageslist tr td.handle').addClass('handler');}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_comment.js b/dotclear._no/admin/js/_comment.js new file mode 100644 index 0000000..86762e0 --- /dev/null +++ b/dotclear._no/admin/js/_comment.js @@ -0,0 +1,2 @@ +'use strict';$(function(){if(typeof jsToolBar!=='undefined'&&$.isFunction(jsToolBar)){const tbComment=new jsToolBar(document.getElementById('comment_content'));tbComment.draw('xhtml');} +$('#comment-form input[name="delete"]').on('click',function(){return window.confirm(dotclear.msg.confirm_delete_comment);});}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_comments.js b/dotclear._no/admin/js/_comments.js new file mode 100644 index 0000000..4ab69c2 --- /dev/null +++ b/dotclear._no/admin/js/_comments.js @@ -0,0 +1,2 @@ +'use strict';dotclear.viewCommentContent=function(line,action,e){action=action||'toggle';if($(line).attr('id')==undefined){return;} +const commentId=$(line).attr('id').substr(1);const lineId=`ce${commentId}`;let tr=document.getElementById(lineId);const clean=(e.metaKey||$(line).hasClass('sts-junk'));if(!tr){dotclear.getCommentContent(commentId,function(content){if(content){tr=document.createElement('tr');tr.id=lineId;const td=document.createElement('td');td.colSpan=$(line).children('td').length;td.className='expand';tr.appendChild(td);$(td).append(content);$(line).addClass('expand');line.parentNode.insertBefore(tr,line.nextSibling);}else{$(line).removeClass('expand');}},{clean:clean});}else{$(tr).toggle();$(line).toggleClass('expand');}};$(function(){$.expandContent({line:$('#form-comments tr:not(.line)'),lines:$('#form-comments tr.line'),callback:dotclear.viewCommentContent});$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this,undefined,'#form-comments td input[type=checkbox]','#form-comments #do-action');});$('#form-comments td input[type=checkbox]').enableShiftClick();dotclear.commentsActionsHelper();dotclear.condSubmit('#form-comments td input[type=checkbox]','#form-comments #do-action');dotclear.responsiveCellHeaders(document.querySelector('#form-comments table'),'#form-comments table',1);$('form input[type=submit][name=delete_all_spam]').on('click',function(){return window.confirm(dotclear.msg.confirm_spam_delete);});}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_comments_actions.js b/dotclear._no/admin/js/_comments_actions.js new file mode 100644 index 0000000..ebd0da9 --- /dev/null +++ b/dotclear._no/admin/js/_comments_actions.js @@ -0,0 +1 @@ +'use strict';$(function(){dotclear.condSubmit('table.posts-list td input[type=checkbox]','input[type=submit]');}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_index.js b/dotclear._no/admin/js/_index.js new file mode 100644 index 0000000..ff6efb3 --- /dev/null +++ b/dotclear._no/admin/js/_index.js @@ -0,0 +1,17 @@ +'use strict';dotclear.dbCommentsCount=function(){const params={f:'getCommentsCount',xd_check:dotclear.nonce,};$.get('services.php',params,function(data){if($('rsp[status=failed]',data).length>0){window.console.log('Dotclear REST server error');}else{const nb=$('rsp>count',data).attr('ret');if(nb!=dotclear.dbCommentsCount_Counter){const icon=$('#dashboard-main #icons p a[href="comments.php"]');if(icon.length){const nb_label=icon.children('span.db-icon-title');if(nb_label.length){nb_label.text(nb);}} +dotclear.dbCommentsCount_Counter=nb;}}});};dotclear.dbPostsCount=function(){const params={f:'getPostsCount',xd_check:dotclear.nonce,};$.get('services.php',params,function(data){if($('rsp[status=failed]',data).length>0){window.console.log('Dotclear REST server error');}else{const nb=$('rsp>count',data).attr('ret');if(nb!=dotclear.dbPostsCount_Counter){const icon=$('#dashboard-main #icons p a[href="posts.php"]');if(icon.length){const nb_label=icon.children('span.db-icon-title');if(nb_label.length){nb_label.text(nb);}} +dotclear.dbPostsCount_Counter=nb;}}});};$(function(){function quickPost(f,status){if(typeof jsToolBar!=='undefined'&&$.isFunction(jsToolBar)&&contentTb.getMode()=='wysiwyg'){contentTb.syncContents('iframe');} +const params={f:'quickPost',xd_check:dotclear.nonce,post_title:$('#post_title',f).val(),post_content:$('#post_content',f).val(),cat_id:$('#cat_id',f).val(),post_status:status,post_format:$('#post_format',f).val(),post_lang:$('#post_lang',f).val(),new_cat_title:$('#new_cat_title',f).val(),new_cat_parent:$('#new_cat_parent',f).val()};$('p.qinfo',f).remove();$.post('services.php',params,function(data){let msg;if($('rsp[status=failed]',data).length>0){msg='

    '+dotclear.msg.error+' '+$('rsp',data).text()+'

    ';}else{msg='

    '+dotclear.msg.entry_created+' - '+ +dotclear.msg.edit_entry+'';if($('rsp>post',data).attr('post_status')==1){msg+=' - '+ +dotclear.msg.view_entry+'';} +msg+='

    ';$('#post_title',f).val('');$('#post_content',f).val('');$('#post_content',f).change();if(typeof jsToolBar!=='undefined'&&$.isFunction(jsToolBar)&&contentTb.getMode()=='wysiwyg'){contentTb.syncContents('textarea');} +$('#cat_id',f).val('0');$('#new_cat_title',f).val('');$('#new_cat_parent',f).val('0');} +$('fieldset',f).prepend(msg);});} +const f=$('#quick-entry');if(f.length>0){if(typeof jsToolBar!=='undefined'&&$.isFunction(jsToolBar)){var contentTb=new jsToolBar($('#post_content',f)[0]);contentTb.switchMode($('#post_format',f).val());} +$('input[name=save]',f).on('click',function(){quickPost(f,-2);return false;});if($('input[name=save-publish]',f).length>0){var btn=$('');$('input[name=save-publish]',f).remove();$('input[name=save]',f).after(btn).after(' ');btn.on('click',function(){quickPost(f,1);return false;});} +$('#new_cat').toggleWithLegend($('#new_cat').parent().children().not('#new_cat'),{legend_click:true});} +$('#quick h3').toggleWithLegend($('#quick').children().not('h3'),{legend_click:true,user_pref:'dcx_quick_entry'});let params={f:'checkCoreUpdate',xd_check:dotclear.nonce};$.post('services.php',params,function(data){if($('rsp[status=failed]',data).length>0){}else{if($('rsp>update',data).attr('check')==1){const xml=$('rsp>update',data).attr('ret');$('#content h2').after(xml);dotclear.outgoingLinks('#ajax-update a');}}});params={f:'checkNewsUpdate',xd_check:dotclear.nonce};$.post('services.php',params,function(data){if($('rsp[status=failed]',data).length>0){}else{if($('rsp>news',data).attr('check')==1){const xml=$('rsp>news',data).attr('ret');if($('#dashboard-boxes').length==0){$('#dashboard-main').append('
    ');} +if($('#dashboard-boxes div.db-items').length==0){$('#dashboard-boxes').prepend('
    ');} +$('#dashboard-boxes div.db-items').prepend(xml);dotclear.outgoingLinks('#ajax-news a');}}});if($('#dashboard-main #icons p a[href="comments.php"]').length){dotclear.dbCommentsCount();dotclear.dbCommentsCount_Timer=setInterval(dotclear.dbCommentsCount,60*1000);} +if($('#dashboard-main #icons p a[href="posts.php"]').length){dotclear.dbPostsCount();dotclear.dbPostsCount_Timer=setInterval(dotclear.dbPostsCount,600*1000);} +if(!dotclear.data.noDragDrop){const set_positions=function(sel,id){const list=$(sel).sortable("toArray").join();const params={f:'setDashboardPositions',xd_check:dotclear.nonce,id:id,list:list};$.post('services.php',params,function(){});};const init_positions=function(sel,id){$(sel).sortable({cursor:'move',opacity:0.5,delay:200,distance:10,tolerance:"pointer",update:function(){set_positions(sel,id);},start:function(){$(sel).addClass('sortable-area');},stop:function(){$(sel).removeClass('sortable-area');}});};const reset_positions=function(sel){$(sel).sortable('destroy');};const areas=[['#dashboard-main','main_order'],['#dashboard-boxes','boxes_order'],['#db-items','boxes_items_order'],['#db-contents','boxes_contents_order']];$('#dragndrop').on('click',function(){Object.assign(dotclear,getData('dotclear_dragndrop'));if($(this).is(':checked')){areas.forEach(element=>init_positions(element[0],element[1]));$(this).prop('title',dotclear.dragndrop_on);$('#dragndrop-label').text(dotclear.dragndrop_on);}else{areas.forEach(element=>reset_positions(element[0]));$(this).prop('title',dotclear.dragndrop_off);$('#dragndrop-label').text(dotclear.dragndrop_off);}});}}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_install.js b/dotclear._no/admin/js/_install.js new file mode 100644 index 0000000..b870bd2 --- /dev/null +++ b/dotclear._no/admin/js/_install.js @@ -0,0 +1 @@ +'use strict';$(function(){const login_re=new RegExp('[^A-Za-z0-9@._-]+','g');$('#u_firstname').on('keyup',function(){$('#u_login').val(this.value.toLowerCase().replace(login_re,'').substring(0,32));});$('#u_login').on('keyup',function(){$(this).val(this.value.replace(login_re,''));});const texts=getData('install');$('#u_pwd').pwstrength({texts:texts});$('#u_login').parent().after($(''));const show=getData('install_show');const password_link=$(''+show+'').on('click',function(){$('#password').show();$(this).remove();return false;});$('#password').hide().before(password_link);}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_langs.js b/dotclear._no/admin/js/_langs.js new file mode 100644 index 0000000..5b0b41a --- /dev/null +++ b/dotclear._no/admin/js/_langs.js @@ -0,0 +1 @@ +'use strict';$(function(){$('table.plugins form input[type=submit][name=delete]').on('click',function(){const l_name=$(this).parents('tr.line').find('td:first').text();return window.confirm(dotclear.msg.confirm_delete_lang.replace('%s',l_name));});}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_media.js b/dotclear._no/admin/js/_media.js new file mode 100644 index 0000000..1e3fe50 --- /dev/null +++ b/dotclear._no/admin/js/_media.js @@ -0,0 +1,14 @@ +'use strict';(function($){$.fn.enhancedUploader=function(){return this.each(function(){const me=$(this);const $container=$(me).parent();function enableButton(button){button.prop('disabled',false).removeClass('disabled');} +function disableButton(button){button.prop('disabled',true).addClass('disabled');} +function displayMessageInQueue(n){let msg='';if(n==1){msg=dotclear.jsUpload.msg.file_in_queue;}else if(n>1){msg=dotclear.jsUpload.msg.files_in_queue;msg=msg.replace(/%d/,n);}else{msg=dotclear.jsUpload.msg.no_file_in_queue;} +$('.queue-message',me).html(msg);} +$('.button.choose_files').on('click',function(e){if($container.hasClass('enhanced_uploader')){$('#upfile').trigger('click');e.preventDefault();}});$('.button.cancel','#fileupload .fileupload-buttonbar').on('click',function(){$('.button.cancel','#fileupload .fileupload-buttonbar').hide();disableButton($('.button.start','#fileupload .fileupload-buttonbar'));displayMessageInQueue(0);});$(me).on('click','.cancel',function(){if($('.fileupload-ctrl .files .template-upload',me).length==0){$('.button.cancel','#fileupload .fileupload-buttonbar').hide();disableButton($('.button.start','#fileupload .fileupload-buttonbar'));} +displayMessageInQueue($('.files .template-upload',me).length);});$('.button.clean',me).on('click',function(e){$('.fileupload-ctrl .files .template-download',me).slideUp(500,function(){$(this).remove();});$(this).hide();e.preventDefault();});$(me).fileupload({url:$(me).attr('action'),autoUpload:false,sequentialUploads:true,uploadTemplateId:null,downloadTemplateId:null,uploadTemplate:template_upload,downloadTemplate:template_download}).bind('fileuploadadd',function(){$('.button.cancel').css('display','inline-block');$('#fileupload .fileupload-buttonbar').show();enableButton($('.button.start','#fileupload .fileupload-buttonbar'));}).bind('fileuploadadded',function(){displayMessageInQueue($('.files .template-upload',me).length);}).bind('fileuploaddone',function(e,data){if(data.result.files[0].html!==undefined){$('.media-list .files-group').append(data.result.files[0].html);$('#form-medias .hide').removeClass('hide');} +$('.button.clean').css('display','inline-block');$(me).show();}).bind('fileuploadalways',function(){displayMessageInQueue($('.files .template-upload',me).length);if($('.fileupload-ctrl .files .template-upload',me).length==0){$('.button.cancel','#fileupload .fileupload-buttonbar').hide();disableButton($('.button.start','#fileupload .fileupload-buttonbar'));}});let $msg;let label;if($container.hasClass('enhanced_uploader')){$msg=dotclear.msg.enhanced_uploader_disable;label=dotclear.jsUpload.msg.choose_files;$(me).fileupload({disabled:false});displayMessageInQueue(0);disableButton($('.button.start','#fileupload .fileupload-buttonbar'));}else{$msg=dotclear.msg.enhanced_uploader_activate;label=dotclear.jsUpload.msg.choose_file;$(me).fileupload({disabled:true});} +$(`

    `).on('click',function(e){if($container.hasClass('enhanced_uploader')){$msg=dotclear.msg.enhanced_uploader_activate;label=dotclear.jsUpload.msg.choose_file;$('#upfile').attr('multiple',false);enableButton($('.button.start','#fileupload .fileupload-buttonbar'));$('.files .upload-file',me).remove();$('.button.cancel,.button.clean','#fileupload .fileupload-buttonbar').hide();$(me).fileupload({disabled:true});$('.queue-message',me).html('').hide();}else{$msg=dotclear.msg.enhanced_uploader_disable;label=dotclear.jsUpload.msg.choose_files;$('#upfile').attr('multiple',true);const startButton=$('.button.start');const buttonBar=$('#fileupload .fileupload-buttonbar');disableButton(startButton);disableButton(buttonBar);startButton.css('display','inline-block');buttonBar.show();$(me).fileupload({disabled:false});$('.queue-message',me).show();displayMessageInQueue(0);} +$(this).find('button').text($msg);$('.add-label',me).text(label);$container.toggleClass('enhanced_uploader');e.preventDefault();}).appendTo(me);});};})(jQuery);$(function(){$('#fileupload').enhancedUploader();$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this,undefined,'#form-medias input[type="checkbox"]','#form-medias #delete_medias');});dotclear.condSubmit('#form-medias input[type="checkbox"]','#form-medias #delete_medias');$('#form-medias #delete_medias').on('click',function(e){const count_checked=$('input[name="medias[]"]:checked',$('#form-medias')).length;if(count_checked==0){e.preventDefault();return false;} +return window.confirm(dotclear.msg.confirm_delete_medias.replace('%d',count_checked));});$('.modal-image').magnificPopup({type:'image'});$('#form-medias').on('click','.media-item .attach-media',function(e){const parts=$(this).prop('href').split('?');const str_params=parts[1].split('&');let postData={};for(let n=0;n

    ');$(a).on('click',function(){$.get('services.php',{f:'getZipMediaContent',id:mediaId},function(data){const rsp=$(data).children('rsp')[0];if(rsp.attributes[0].value=='ok'){const div=document.createElement('div');const list=document.createElement('ul');let expanded=false;$(div).css({overflow:'auto',margin:'1em 0',padding:'1px 0.5em'});$(div).addClass('color-div');$(div).append(list);This.before(div);$(a).hide();$(div).before('

    '+dotclear.msg.zip_file_content+'

    ');$(rsp).find('file').each(function(){$(list).append('
  • '+$(this).text()+'
  • ');if($(div).height()>200&&!expanded){$(div).css({height:'200px'});expanded=true;}});}else{window.alert($(rsp).find('message').text());}});return false;});});$('#file-unzip').on('submit',function(){if($(this).find('#inflate_mode').val()=='current'){return window.confirm(dotclear.msg.confirm_extract_current);} +return true;});$('#delete-form input[name="delete"]').on('click',function(){let m_name=$('#delete-form input[name="remove"]').val();return window.confirm(dotclear.msg.confirm_delete_media.replace('%s',m_name));});$('#save_settings').on('submit',function(){$('input[name="pref_src"]').val($('input[name="src"][type=radio]:checked').attr('value'));$('input[name="pref_alignment"]').val($('input[name="alignment"][type=radio]:checked').attr('value'));$('input[name="pref_insertion"]').val($('input[name="insertion"][type=radio]:checked').attr('value'));$('input[name="pref_legend"]').val($('input[name="legend"][type=radio]:checked').attr('value'));});$('#media-insert-form :input:visible:enabled:checked:first, #media-insert-form :input:visible:enabled:first').trigger('focus');dotclear.enterKeyInForm('#media-insert-form','#media-insert-ok','#media-insert-cancel');}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_permissions.js b/dotclear._no/admin/js/_permissions.js new file mode 100644 index 0000000..1547911 --- /dev/null +++ b/dotclear._no/admin/js/_permissions.js @@ -0,0 +1,6 @@ + +jQuery.fn.updatePermissionsForm=function(){return this.each(function(){var perms={};var re=/^perm\[(.+?)\]\[(.+?)\]$/;var e,prop;for(var i=0;i0){$(checkboxes).each(function(){if(this.checked){checked=true;}});if(!checked){return false;}} +if(action=='delete'){return window.confirm(dotclear.msg.confirm_delete_plugins);}}else{const module=mvalues[1];if(action=='delete'){return window.confirm(dotclear.msg.confirm_delete_plugin.replace('%s',module));}} +return true;});});}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_popup_link.js b/dotclear._no/admin/js/_popup_link.js new file mode 100644 index 0000000..4cc3326 --- /dev/null +++ b/dotclear._no/admin/js/_popup_link.js @@ -0,0 +1 @@ +'use strict';$(function(){$('#link-insert-ok').prop('disabled',true);$('#link-insert-ok').addClass('disabled');$('#href').on('keyup',function(){$('#link-insert-ok').prop('disabled',(this.value==''?true:false));$('#link-insert-ok').toggleClass('disabled',(this.value==''?true:false));});$('#href').trigger('focus');dotclear.enterKeyInForm('#link-insert-form','#link-insert-ok','#link-insert-cancel');}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_popup_posts.js b/dotclear._no/admin/js/_popup_posts.js new file mode 100644 index 0000000..c6c5612 --- /dev/null +++ b/dotclear._no/admin/js/_popup_posts.js @@ -0,0 +1 @@ +'use strict';$(function(){$('#type').trigger('focus');}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_post.js b/dotclear._no/admin/js/_post.js new file mode 100644 index 0000000..a3b93f4 --- /dev/null +++ b/dotclear._no/admin/js/_post.js @@ -0,0 +1,4 @@ +'use strict';dotclear.viewCommentContent=function(line,action,e){action=action||'toggle';if($(line).attr('id')==undefined){return;} +const commentId=$(line).attr('id').substr(1);const lineId=`ce${commentId}`;let tr=document.getElementById(lineId);const clean=(e.metaKey||$(line).hasClass('sts-junk'));if(!tr){dotclear.getCommentContent(commentId,function(content){if(content){tr=document.createElement('tr');tr.id=lineId;const td=document.createElement('td');td.colSpan=$(line).children('td').length;td.className='expand';tr.appendChild(td);$(td).append(content);$(line).addClass('expand');line.parentNode.insertBefore(tr,line.nextSibling);}else{$(line).removeClass('expand');}},{ip:false,clean:clean});}else{$(tr).toggle();$(line).toggleClass('expand');}};$(function(){let $preview_url=$('#post-preview').attr('href');if($preview_url){let $a=document.createElement('a');$a.href=$('#post-preview').attr('href');$preview_url=$a.href;if(window.location.protocol==$preview_url.substring(0,window.location.protocol.length)){$('#post-preview').magnificPopup({type:'iframe',iframe:{patterns:{dotclear_preview:{index:$preview_url,src:$preview_url}}}});}else{$('#post-preview').on('click',function(e){e.preventDefault();window.open($(this).attr('href'));});}} +$('#edit-entry').onetabload(function(){dotclear.hideLockable();const post_dtPick=new datePicker($('#post_dt').get(0));post_dtPick.img_top='1.5em';post_dtPick.draw();$('input[name="delete"]').on('click',function(){return window.confirm(dotclear.msg.confirm_delete_post);});$('#notes-area label').toggleWithLegend($('#notes-area').children().not('label'),{user_pref:'dcx_post_notes',legend_click:true,hide:$('#post_notes').val()==''});$('#post_lang').parent().children('label').toggleWithLegend($('#post_lang'),{user_pref:'dcx_post_lang',legend_click:true});$('#post_password').parent().children('label').toggleWithLegend($('#post_password'),{user_pref:'dcx_post_password',legend_click:true,hide:$('#post_password').val()==''});$('#post_status').parent().children('label').toggleWithLegend($('#post_status'),{user_pref:'dcx_post_status',legend_click:true});$('#post_dt').parent().children('label').toggleWithLegend($('#post_dt').parent().children().not('label'),{user_pref:'dcx_post_dt',legend_click:true});$('#label_format').toggleWithLegend($('#label_format').parent().children().not('#label_format'),{user_pref:'dcx_post_format',legend_click:true});$('#label_cat_id').toggleWithLegend($('#label_cat_id').parent().children().not('#label_cat_id'),{user_pref:'dcx_cat_id',legend_click:true});$('#create_cat').toggleWithLegend($('#create_cat').parent().children().not('#create_cat'),{legend_click:true});$('#label_comment_tb').toggleWithLegend($('#label_comment_tb').parent().children().not('#label_comment_tb'),{user_pref:'dcx_comment_tb',legend_click:true});$('#post_url').parent().children('label').toggleWithLegend($('#post_url').parent().children().not('label'),{user_pref:'post_url',legend_click:true});$('#excerpt-area label').toggleWithLegend($('#excerpt-area').children().not('label'),{user_pref:'dcx_post_excerpt',legend_click:true,hide:$('#post_excerpt').val()==''});$('a.attachment-remove').on('click',function(){this.href='';const m_name=$(this).parents('ul').find('li:first>a').attr('title');if(window.confirm(dotclear.msg.confirm_remove_attachment.replace('%s',m_name))){var f=$('#attachment-remove-hide').get(0);f.elements.media_id.value=this.id.substring(11);f.submit();} +return false;});});$('#comments').onetabload(function(){$.expandContent({line:$('#form-comments .comments-list tr:not(.line)'),lines:$('#form-comments .comments-list tr.line'),callback:dotclear.viewCommentContent});$('#form-comments .checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this);});dotclear.commentsActionsHelper();});$('#trackbacks').onetabload(function(){$.expandContent({line:$('#form-trackbacks .comments-list tr:not(.line)'),lines:$('#form-trackbacks .comments-list tr.line'),callback:dotclear.viewCommentContent});$('#form-trackbacks .checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this);});dotclear.commentsActionsHelper();});$('#add-comment').onetabload(function(){commentTb.draw('xhtml');});}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_posts_actions.js b/dotclear._no/admin/js/_posts_actions.js new file mode 100644 index 0000000..077c48f --- /dev/null +++ b/dotclear._no/admin/js/_posts_actions.js @@ -0,0 +1,2 @@ +'use strict';$(function(){const new_auth_id=$('#new_auth_id');if(new_auth_id.length){const usersList=getData('users_list');new_auth_id.autocomplete(usersList,{delay:1000,matchSubset:true,matchContains:true});} +$('#new_cat').toggleWithLegend($('#new_cat').parent().children().not('#new_cat'),{legend_click:true});dotclear.condSubmit('table.posts-list td input[type=checkbox]','input[type=submit]');}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_posts_list.js b/dotclear._no/admin/js/_posts_list.js new file mode 100644 index 0000000..6daa7ba --- /dev/null +++ b/dotclear._no/admin/js/_posts_list.js @@ -0,0 +1,2 @@ +'use strict';dotclear.viewPostContent=function(line,action,e){action=action||'toggle';if($(line).attr('id')==undefined){return;} +const postId=$(line).attr('id').substr(1);const lineId=`pe${postId}`;let tr=document.getElementById(lineId);if(!tr){dotclear.getEntryContent(postId,function(content){if(content){tr=document.createElement('tr');tr.id=lineId;const td=document.createElement('td');td.colSpan=$(line).children('td').length;td.className='expand';tr.appendChild(td);$(td).append(content);$(line).addClass('expand');line.parentNode.insertBefore(tr,line.nextSibling);}else{$(line).toggleClass('expand');}},{clean:(e.metaKey)});}else{$(tr).toggle();$(line).toggleClass('expand');}};$(function(){$('#type').on('change',function(){this.form.submit();});$.expandContent({line:$('#form-entries tr:not(.line)'),lines:$('#form-entries tr.line'),callback:dotclear.viewPostContent});$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this,undefined,'#form-entries td input[type=checkbox]','#form-entries #do-action');});$('#form-entries td input[type=checkbox]').enableShiftClick();dotclear.condSubmit('#form-entries td input[type=checkbox]','#form-entries #do-action');dotclear.postsActionsHelper();dotclear.responsiveCellHeaders(document.querySelector('#form-entries table'),'#form-entries table',1);}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_preferences-dragdrop.js b/dotclear._no/admin/js/_preferences-dragdrop.js new file mode 100644 index 0000000..56c7040 --- /dev/null +++ b/dotclear._no/admin/js/_preferences-dragdrop.js @@ -0,0 +1 @@ +'use strict';$(function(){$('#my-favs ul').sortable({'cursor':'move'});$('#my-favs ul, #my-favs ul *').css({'cursor':'move'});$('#my-favs ul input').css({'cursor':'auto'});$('#favs-form').on('submit',function(){let order=[];$('#my-favs ul li input.position').each(function(){order.push(this.name.replace(/^order\[([^\]]+)\]$/,'$1'));});$('input[name=favs_order]')[0].value=order.join(',');return true;});$('#my-favs ul li input.position').hide();}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_preferences.js b/dotclear._no/admin/js/_preferences.js new file mode 100644 index 0000000..0ced61c --- /dev/null +++ b/dotclear._no/admin/js/_preferences.js @@ -0,0 +1,4 @@ +'use strict';$(function(){if($('#new_pwd').length==0){return;} +const texts=getData('preferences');$('#new_pwd').pwstrength({texts:texts});const user_email=$('#user_email').val();$('#user-form').on('submit',function(){var e=this.elements.cur_pwd;if(e.value!=''){return true;} +if($('#user_email').val()!=user_email||$('#new_pwd').val()!=''){$(e).addClass('missing').on('focusout',function(){$(this).removeClass('missing');});e.focus();return false;} +return true;});}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_trackbacks.js b/dotclear._no/admin/js/_trackbacks.js new file mode 100644 index 0000000..085e913 --- /dev/null +++ b/dotclear._no/admin/js/_trackbacks.js @@ -0,0 +1 @@ +'use strict';$(function(){$('#tb_excerpt').on('keypress',function(){if(this.value.length>255){this.value=this.value.substring(0,255);}});}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_update.js b/dotclear._no/admin/js/_update.js new file mode 100644 index 0000000..fab7f82 --- /dev/null +++ b/dotclear._no/admin/js/_update.js @@ -0,0 +1 @@ +'use strict';$(function(){$('form input[type=submit][name=b_del]').on('click',function(){return window.confirm(dotclear.msg.confirm_delete_backup);});$('form input[type=submit][name=b_revert]').on('click',function(){return window.confirm(dotclear.msg.confirm_revert_backup);});}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_user.js b/dotclear._no/admin/js/_user.js new file mode 100644 index 0000000..566c1ec --- /dev/null +++ b/dotclear._no/admin/js/_user.js @@ -0,0 +1,2 @@ +'use strict';$(function(){if($('#new_pwd').length==0){return;} +const texts=getData('user');$('#new_pwd').pwstrength({texts:texts});}); \ No newline at end of file diff --git a/dotclear._no/admin/js/_users.js b/dotclear._no/admin/js/_users.js new file mode 100644 index 0000000..968dc1b --- /dev/null +++ b/dotclear._no/admin/js/_users.js @@ -0,0 +1,6 @@ +'use strict';$(function(){$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this,undefined,'#form-users input[type="checkbox"]','#form-users #do-action');});dotclear.condSubmit('#form-users input[type="checkbox"]','#form-users #do-action');dotclear.responsiveCellHeaders(document.querySelector('#form-users table'),'#form-users table',1);$('#form-users').submit(function(){const action=$(this).find('select[name="action"]').val();let user_ids=[];let nb_posts=[];let i;let msg_cannot_delete=false;$(this).find('input[name="users[]"]').each(function(){user_ids.push(this);});$(this).find('input[name="nb_post[]"]').each(function(){nb_posts.push(this.value);});if(action=='deleteuser'){for(i=0;i0){if(user_ids[i].checked==true){msg_cannot_delete=true;user_ids[i].checked=false;}}} +if(msg_cannot_delete==true){window.alert(dotclear.msg.cannot_delete_users);}} +let selectfields=0;for(i=0;i and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/dotclear._no/admin/js/codemirror/addon/display/fullscreen.css b/dotclear._no/admin/js/codemirror/addon/display/fullscreen.css new file mode 100644 index 0000000..437acd8 --- /dev/null +++ b/dotclear._no/admin/js/codemirror/addon/display/fullscreen.css @@ -0,0 +1,6 @@ +.CodeMirror-fullscreen { + position: fixed; + top: 0; left: 0; right: 0; bottom: 0; + height: auto; + z-index: 9; +} diff --git a/dotclear._no/admin/js/codemirror/addon/display/fullscreen.js b/dotclear._no/admin/js/codemirror/addon/display/fullscreen.js new file mode 100644 index 0000000..167d216 --- /dev/null +++ b/dotclear._no/admin/js/codemirror/addon/display/fullscreen.js @@ -0,0 +1,5 @@ +(function(mod){if(typeof exports=="object"&&typeof module=="object") +mod(require("../../lib/codemirror"));else if(typeof define=="function"&&define.amd) +define(["../../lib/codemirror"],mod);else +mod(CodeMirror);})(function(CodeMirror){"use strict";CodeMirror.defineOption("fullScreen",false,function(cm,val,old){if(old==CodeMirror.Init)old=false;if(!old==!val)return;if(val)setFullscreen(cm);else setNormal(cm);});function setFullscreen(cm){var wrap=cm.getWrapperElement();cm.state.fullScreenRestore={scrollTop:window.pageYOffset,scrollLeft:window.pageXOffset,width:wrap.style.width,height:wrap.style.height};wrap.style.width="";wrap.style.height="auto";wrap.className+=" CodeMirror-fullscreen";document.documentElement.style.overflow="hidden";cm.refresh();} +function setNormal(cm){var wrap=cm.getWrapperElement();wrap.className=wrap.className.replace(/\s*CodeMirror-fullscreen\b/,"");document.documentElement.style.overflow="";var info=cm.state.fullScreenRestore;wrap.style.width=info.width;wrap.style.height=info.height;window.scrollTo(info.scrollLeft,info.scrollTop);cm.refresh();}}); \ No newline at end of file diff --git a/dotclear._no/admin/js/codemirror/addon/edit/closebrackets.js b/dotclear._no/admin/js/codemirror/addon/edit/closebrackets.js new file mode 100644 index 0000000..1531fa6 --- /dev/null +++ b/dotclear._no/admin/js/codemirror/addon/edit/closebrackets.js @@ -0,0 +1,29 @@ +(function(mod){if(typeof exports=="object"&&typeof module=="object") +mod(require("../../lib/codemirror"));else if(typeof define=="function"&&define.amd) +define(["../../lib/codemirror"],mod);else +mod(CodeMirror);})(function(CodeMirror){var defaults={pairs:"()[]{}''\"\"",closeBefore:")]}'\":;>",triples:"",explode:"[]{}"};var Pos=CodeMirror.Pos;CodeMirror.defineOption("autoCloseBrackets",false,function(cm,val,old){if(old&&old!=CodeMirror.Init){cm.removeKeyMap(keyMap);cm.state.closeBrackets=null;} +if(val){ensureBound(getOption(val,"pairs")) +cm.state.closeBrackets=val;cm.addKeyMap(keyMap);}});function getOption(conf,name){if(name=="pairs"&&typeof conf=="string")return conf;if(typeof conf=="object"&&conf[name]!=null)return conf[name];return defaults[name];} +var keyMap={Backspace:handleBackspace,Enter:handleEnter};function ensureBound(chars){for(var i=0;i=0;i--){var cur=ranges[i].head;cm.replaceRange("",Pos(cur.line,cur.ch-1),Pos(cur.line,cur.ch+1),"+delete");}} +function handleEnter(cm){var conf=getConfig(cm);var explode=conf&&getOption(conf,"explode");if(!explode||cm.getOption("disableInput"))return CodeMirror.Pass;var ranges=cm.listSelections();for(var i=0;i0;return{anchor:new Pos(sel.anchor.line,sel.anchor.ch+(inverted?-1:1)),head:new Pos(sel.head.line,sel.head.ch+(inverted?1:-1))};} +function handleChar(cm,ch){var conf=getConfig(cm);if(!conf||cm.getOption("disableInput"))return CodeMirror.Pass;var pairs=getOption(conf,"pairs");var pos=pairs.indexOf(ch);if(pos==-1)return CodeMirror.Pass;var closeBefore=getOption(conf,"closeBefore");var triples=getOption(conf,"triples");var identical=pairs.charAt(pos+1)==ch;var ranges=cm.listSelections();var opening=pos%2==0;var type;for(var i=0;i=0&&cm.getRange(cur,Pos(cur.line,cur.ch+3))==ch+ch+ch) +curType="skipThree";else +curType="skip";}else if(identical&&cur.ch>1&&triples.indexOf(ch)>=0&&cm.getRange(Pos(cur.line,cur.ch-2),cur)==ch+ch){if(cur.ch>2&&/\bstring/.test(cm.getTokenTypeAt(Pos(cur.line,cur.ch-2))))return CodeMirror.Pass;curType="addFour";}else if(identical){var prev=cur.ch==0?" ":cm.getRange(Pos(cur.line,cur.ch-1),cur) +if(!CodeMirror.isWordChar(next)&&prev!=ch&&!CodeMirror.isWordChar(prev))curType="both";else return CodeMirror.Pass;}else if(opening&&(next.length===0||/\s/.test(next)||closeBefore.indexOf(next)>-1)){curType="both";}else{return CodeMirror.Pass;} +if(!type)type=curType;else if(type!=curType)return CodeMirror.Pass;} +var left=pos%2?pairs.charAt(pos-1):ch;var right=pos%2?ch:pairs.charAt(pos+1);cm.operation(function(){if(type=="skip"){cm.execCommand("goCharRight");}else if(type=="skipThree"){for(var i=0;i<3;i++) +cm.execCommand("goCharRight");}else if(type=="surround"){var sels=cm.getSelections();for(var i=0;i",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<","<":">>",">":"<<"};function bracketRegex(config){return config&&config.bracketRegex||/[(){}[\]]/} +function findMatchingBracket(cm,where,config){var line=cm.getLineHandle(where.line),pos=where.ch-1;var afterCursor=config&&config.afterCursor +if(afterCursor==null) +afterCursor=/(^| )cm-fat-cursor($| )/.test(cm.getWrapperElement().className) +var re=bracketRegex(config) +var match=(!afterCursor&&pos>=0&&re.test(line.text.charAt(pos))&&matching[line.text.charAt(pos)])||re.test(line.text.charAt(pos+1))&&matching[line.text.charAt(++pos)];if(!match)return null;var dir=match.charAt(1)==">"?1:-1;if(config&&config.strict&&(dir>0)!=(pos==where.ch))return null;var style=cm.getTokenTypeAt(Pos(where.line,pos+1));var found=scanForBracket(cm,Pos(where.line,pos+(dir>0?1:0)),dir,style||null,config);if(found==null)return null;return{from:Pos(where.line,pos),to:found&&found.pos,match:found&&found.ch==match.charAt(0),forward:dir>0};} +function scanForBracket(cm,where,dir,style,config){var maxScanLen=(config&&config.maxScanLineLength)||10000;var maxScanLines=(config&&config.maxScanLines)||1000;var stack=[];var re=bracketRegex(config) +var lineEnd=dir>0?Math.min(where.line+maxScanLines,cm.lastLine()+1):Math.max(cm.firstLine()-1,where.line-maxScanLines);for(var lineNo=where.line;lineNo!=lineEnd;lineNo+=dir){var line=cm.getLine(lineNo);if(!line)continue;var pos=dir>0?0:line.length-1,end=dir>0?line.length:-1;if(line.length>maxScanLen)continue;if(lineNo==where.line)pos=where.ch-(dir<0?1:0);for(;pos!=end;pos+=dir){var ch=line.charAt(pos);if(re.test(ch)&&(style===undefined||cm.getTokenTypeAt(Pos(lineNo,pos+1))==style)){var match=matching[ch];if(match&&(match.charAt(1)==">")==(dir>0))stack.push(ch);else if(!stack.length)return{pos:Pos(lineNo,pos),ch:ch};else stack.pop();}}} +return lineNo-dir==(dir>0?cm.lastLine():cm.firstLine())?false:null;} +function matchBrackets(cm,autoclear,config){var maxHighlightLen=cm.state.matchBrackets.maxHighlightLineLength||1000;var marks=[],ranges=cm.listSelections();for(var i=0;i-1?found+pattern.length:found;} +var m=pattern.exec(from?string.slice(from):string);return m?m.index+from+(returnEnd?m[0].length:0):-1;} +return{startState:function(){return{outer:CodeMirror.startState(outer),innerActive:null,inner:null};},copyState:function(state){return{outer:CodeMirror.copyState(outer,state.outer),innerActive:state.innerActive,inner:state.innerActive&&CodeMirror.copyState(state.innerActive.mode,state.inner)};},token:function(stream,state){if(!state.innerActive){var cutOff=Infinity,oldContent=stream.string;for(var i=0;i-1)stream.string=oldContent.slice(0,found);var innerToken=curInner.mode.token(stream,state.inner);if(found>-1)stream.string=oldContent;if(found==stream.pos&&curInner.parseDelimiters) +state.innerActive=state.inner=null;if(curInner.innerStyle){if(innerToken)innerToken=innerToken+" "+curInner.innerStyle;else innerToken=curInner.innerStyle;} +return innerToken;}},indent:function(state,textAfter,line){var mode=state.innerActive?state.innerActive.mode:outer;if(!mode.indent)return CodeMirror.Pass;return mode.indent(state.innerActive?state.inner:state.outer,textAfter,line);},blankLine:function(state){var mode=state.innerActive?state.innerActive.mode:outer;if(mode.blankLine){mode.blankLine(state.innerActive?state.inner:state.outer);} +if(!state.innerActive){for(var i=0;i