Removed
@ -1,932 +0,0 @@
|
|||||||
Dotclear 2.16 - 2020-03-13
|
|
||||||
===========================================================
|
|
||||||
* 🐘 PHP 5.6+ is required, PHP 7.4 compliance
|
|
||||||
* 🛡 Security: all requests from/to Dotclear and DotAddict servers use now HTTPS
|
|
||||||
* jQuery upgraded to 3.4.1, older version will be removed, jQuery not anymore requested for "Remember me" feature
|
|
||||||
* New "static" mode for home page
|
|
||||||
* Media description may now be updated
|
|
||||||
* Add <i [lang="…"]>…</i> support to Dotclear wiki, syntax: ££text[|lang]££
|
|
||||||
* Lib: Update Codemirror to 5.52.0
|
|
||||||
* Lib: Update CKEditor to 4.14.0
|
|
||||||
* Lib: Clearbricks now supports MySQL 8+
|
|
||||||
* 🐛 → Various bugs, a11y concerns and typos fixed
|
|
||||||
* 🌼 → Some locales and cosmetic adjustments
|
|
||||||
|
|
||||||
Dotclear 2.15.3 - 2019-11-28
|
|
||||||
===========================================================
|
|
||||||
* Fix: Avoid weird side-effect of JS minifier
|
|
||||||
* Fix: insertion of default type media (non image/audio/video) in XHTML entries
|
|
||||||
* Fix: Cope with old themes for 'remember me' string defined in JS
|
|
||||||
|
|
||||||
Dotclear 2.15.2 - 2019-10-01
|
|
||||||
===========================================================
|
|
||||||
* Fix: Ajax saving of files in theme editor when using codemirror
|
|
||||||
* Fix: Video insertion with CKEditor or LegacyEditor
|
|
||||||
* Fix: Badge position for dashboard modules counters
|
|
||||||
|
|
||||||
Dotclear 2.15.1 - 2019-08-29
|
|
||||||
===========================================================
|
|
||||||
* Fix: SQL request for CSP unsafe-inline setting
|
|
||||||
* Fix: CKEditor configuration for foreign language (unabled to save post modifications)
|
|
||||||
|
|
||||||
Dotclear 2.15 - 2019-08-13
|
|
||||||
===========================================================
|
|
||||||
* 🐘 PHP 5.6+ is required, PHP 7.3 compliance
|
|
||||||
* Add drag'n'drop sorting system for dashboard blocks
|
|
||||||
* Backend context is preserved on switching blog (as far as possible, depending on user's grants)
|
|
||||||
* No more inline javascript, default/install CSP directive modified accordingly
|
|
||||||
* Add settings (in maintenance plugin) for CSP system
|
|
||||||
* Set correct lang attribute (useful for browser/editor spelling) for content (post/page) depending on entry setting, and CK editor UI in user language
|
|
||||||
* Add spellcheck="true" attribute on input/textarea
|
|
||||||
* Refactoring of notices/messages system on backend
|
|
||||||
* Add undo/redo buttons to CKEditor toolbar
|
|
||||||
* Add title/legend reminder on media popup insertion (1st tab)
|
|
||||||
* Add font loading capabilities for ?pf= system - plugin are now able to load css fonts
|
|
||||||
* Add WebP image format support to Dotclear (may depends on your server PHP capabilities)
|
|
||||||
* Add <sub>…</sub> support in Dotclear wiki, syntax : _indice_
|
|
||||||
* Template system: Allow ?sub for category/categories attributes of tpl:EntryIf, and for url/urls attributes of tpl:CategoryIf
|
|
||||||
* Responsive tables/lists (posts, pages, users, …)
|
|
||||||
* Spams preview (administrative board) now shows HTML code rather than interpreted content
|
|
||||||
* Fix: port used behind reverse proxy (Clearbricks)
|
|
||||||
* Lib: Update Codemirror to 5.48.0
|
|
||||||
* Lib: Update CKEditor to 4.12.0
|
|
||||||
* 🗑 → No more flash players (flv,mp3)
|
|
||||||
* 🐛 → Various bugs, a11y concerns and typos fixed
|
|
||||||
* 🌼 → Some locales and cosmetic adjustments
|
|
||||||
|
|
||||||
Dotclear 2.14.3 - 2018-09-26
|
|
||||||
===========================================================
|
|
||||||
* 🛡 Security: Avoid XML upload in media manager
|
|
||||||
* Fix: Upgrade modification for media_exclusion default setting
|
|
||||||
* Fix: cope with PHP.ini setting memory_limit set to -1 (unlimited)
|
|
||||||
|
|
||||||
Dotclear 2.14.2 - 2018-09-04
|
|
||||||
===========================================================
|
|
||||||
* 🛡 Security: Authenticated cross-site scripting (XSS) was possible due to the .ahtml (or .bhtml, .chtml, …) file extension being allowed in the media manager. Thank's Josiah Pierce for report (CVE-2018-16358)
|
|
||||||
* 🛡 Security: Unregister phar wrapper in order to avoid PHP Phar extension vulerability
|
|
||||||
* Fix: Enter key in some input fields were not redirect to the parent form
|
|
||||||
* Fix: Unable to save modified theme's files in theme editor, when Codemirror is used
|
|
||||||
* Fix: Back to the original global_filters() template function (will be rewritten in the next 2.15)
|
|
||||||
|
|
||||||
Dotclear 2.14.1 - 2018-08-17
|
|
||||||
===========================================================
|
|
||||||
* 🐘 PHP 5.6+ is required - PHP 5.5 is buggy with the 2.14 release
|
|
||||||
* Fix: install wizzard was broken
|
|
||||||
* Fix: smallest admin font size was set when saving user prefs
|
|
||||||
* Fix: minifying JS scripts may cause problems with regular expressions
|
|
||||||
* Fix: empty JS var was set for syntax coloration if disabled
|
|
||||||
|
|
||||||
Dotclear 2.14 - 2018-08-13
|
|
||||||
===========================================================
|
|
||||||
* 🛡 Security: Fix potential reflective XSS, thank's Zekvan Arslan for report (via Daniel Bishtawi from https://www.netsparker.com/)
|
|
||||||
* 🐘 PHP 7.2 compliance
|
|
||||||
* Use specialized fields whenever it's possible (email, …)
|
|
||||||
* Add definition list capabilities (dl, dt, dd) to wiki (= <term>, : <definition>)
|
|
||||||
* Add <sup>…</sup> support in wiki, syntax : ^exponant^
|
|
||||||
* Add syntax property/method to dblayer driver
|
|
||||||
* Replace some js oriented background fading by CSS3 animation
|
|
||||||
* Enhance some visual focus indicators
|
|
||||||
* Enhance key event management in popup (Esc, Enter, …)
|
|
||||||
* Template filters may now be extended (or modified) by 3rd party plugins (via behaviors)
|
|
||||||
* PSR-2 code formatting as far as possible (work in progress)
|
|
||||||
* Add two new ways to order tags (by oldest or newest associated post publication date)
|
|
||||||
* Update Codemirror to 5.38.0
|
|
||||||
* Update CKEditor to 4.9.2
|
|
||||||
* Update jQuery migrate plugin to 1.4.1
|
|
||||||
* Update jQuery UI (custom) 1.12.1
|
|
||||||
* Add a dark mode (via user preferences) for administration, CSS refactoring
|
|
||||||
* Animate some counters on dashboard icons (nb of comments, spam comments and posts)
|
|
||||||
* 🐛 → Various bugs and typos fixed
|
|
||||||
* 🌼 → Some locales and cosmetic adjustments
|
|
||||||
|
|
||||||
Dotclear 2.13.1 - 2018-01-27
|
|
||||||
===========================================================
|
|
||||||
* Fix: Weird behaviour of theme editor when typing any of "t", "r", "u" and "e" characters
|
|
||||||
* Fix: Unable to save an entry with dcLegacyEditor in XHTML mode, visual pane
|
|
||||||
|
|
||||||
Dotclear 2.13 - 2018-01-13
|
|
||||||
===========================================================
|
|
||||||
* 🐘 PHP 5.5+ is required
|
|
||||||
* 🛡 Security: New password management system (including silent migration)
|
|
||||||
* 🛡 Security: Add Referrer-Policy header in admin pages
|
|
||||||
* 🛡 Security: Fix potential XSS - thank's Trí Chim Trích for report
|
|
||||||
* Dotclear news are now displayed in async way by js
|
|
||||||
* Dotclear core update check is now done by async js - a forced check may still be done on <admin>/update.php page
|
|
||||||
* Add utf8mb4 driver (MySQL server 5.7.7+)
|
|
||||||
* Add target="blank" option in simpleMenu
|
|
||||||
* Update CKEditor from 4.6.2 to 4.7.3
|
|
||||||
* Update CodeMirror from 5.25.1 to 5.32.1
|
|
||||||
* Add required attribute for mandatory fields
|
|
||||||
* Fix: Avoid horizontal scrolling table when longest comment's usernames in list of comments
|
|
||||||
* Fix: Cope with MySQLi connection via socket
|
|
||||||
* Fix: Error messages markup and styling
|
|
||||||
* Fix: Set caret at the end of the inserted thing (img, url, blockquote, …) in Legacy editor if current selection is empty
|
|
||||||
* Fix: Cope with query part only in SimpleMenu URLs
|
|
||||||
* 🐛 → Various bugs and typos fixed
|
|
||||||
* 🌼 → Some locales and cosmetic adjustments
|
|
||||||
|
|
||||||
Dotclear 2.12.2 - merged in 2.13
|
|
||||||
===========================================================
|
|
||||||
* Fix: lang attribute was missing on entry alone contexts for currywurst and dotty templatesets
|
|
||||||
* Fix: Add http:// protocol before media.dotaddict.org for csp_admin_img
|
|
||||||
* Fix: tpl:sysIf blog_lang generated code
|
|
||||||
* Fix: Duplicate auto-generated URI (entries)
|
|
||||||
* Fix: Do not use border and background on select to use the system aspect of them in Firefox.
|
|
||||||
* Fix: For select element, target Safari to cope with font-size select/option problem.
|
|
||||||
* Fix: Error messages styling
|
|
||||||
|
|
||||||
Dotclear 2.12.1 - 2017-08-13
|
|
||||||
===========================================================
|
|
||||||
* Fix: 3rd party filters for template tags (std filters are not more modifiable)
|
|
||||||
* Fix: Media filename are now used without modification for media title on upload (advanced mode)
|
|
||||||
|
|
||||||
Dotclear 2.12 - 2017-07-27
|
|
||||||
===========================================================
|
|
||||||
* 🛡 Security: Fix potential XSS
|
|
||||||
* 🛡 Security: Enforce uniqness of the recovery key
|
|
||||||
* 🛡 Security: Switch hash method from sha1 to sha512 (new installation only)
|
|
||||||
* Two new values for base font size (37.5% and 87.5%)
|
|
||||||
* Adaptive admin font size is now optional
|
|
||||||
* Reduce base font size on very small devices
|
|
||||||
* Refactor some functions to closures
|
|
||||||
* No CSP directives in safe mode
|
|
||||||
* Add current blog domain for script and style CSP directives
|
|
||||||
* Backlinks:
|
|
||||||
* Retrieving ping URLs, let trackback first, then pingback, then finally webmention
|
|
||||||
* Get source post content to compose webmention excerpt and retrieve title
|
|
||||||
* Use source post title as blog name if this one is unknown (Anonymous blog is used if neither title nor blog name are known)
|
|
||||||
* Datepicker's look refreshed
|
|
||||||
* Allow 3rd party additional headers (URL handler)
|
|
||||||
* Dublin core metadata removed
|
|
||||||
* Using theme\<theme_name> namespace for _public.php and _prepend.php, in order to simplify theme copy and hack
|
|
||||||
* Temporary password will have to be changed at first login (after resetting password)
|
|
||||||
* Add ukrainian language
|
|
||||||
* French help updated for theme editor
|
|
||||||
* Add an option to disable Dotclear updates check (super-admin only)
|
|
||||||
* Fix: Blogs’ admin (ie not super-admin) got back their blogs’ list but only super-admin may do actions
|
|
||||||
* Fix: Post/page edition layout on different screen sizes
|
|
||||||
* Fix: x-frame-options URL in admin
|
|
||||||
* Fix: Cope with several copies of a same smiley in content
|
|
||||||
* Fix: Allow 3rd party filters for template tags
|
|
||||||
* Fix: Use getURLFor instead of old getBase function for breadcrumb
|
|
||||||
* Fix: Give mysql/mysqli driver choice for DC 1.2 import
|
|
||||||
* Clearbricks lib update from 0.9 to 1.0
|
|
||||||
* jQuery lib update from 2.2.0 to 2.2.4 (last release of jQuery 2.n branch)
|
|
||||||
* CKEditor lib update from 4.6.1 to 4.6.2
|
|
||||||
* CodeMirror lib update from 5.15.3 to 5.25.1
|
|
||||||
* 🐛 → Various bugs and typos fixed
|
|
||||||
* 🌼 → Some locales and cosmetic adjustments
|
|
||||||
* 📣 Warning: Next major release (2.13) will require PHP 5.5+
|
|
||||||
|
|
||||||
Dotclear 2.11.2 - 2016-12-29
|
|
||||||
===========================================================
|
|
||||||
* Fix: Ensure compatibility with old version of PHP (5.3, 5.4)
|
|
||||||
* Fix: New path of CSP report for maintenance deletion task
|
|
||||||
* Fix: Broken entry preview
|
|
||||||
* Fix: Avoid outgoing link on images in media manager
|
|
||||||
* 🌼 → Do not include empty div as it disrupts CSS flexbox system
|
|
||||||
|
|
||||||
Dotclear 2.11.1 - 2016-12-28
|
|
||||||
===========================================================
|
|
||||||
* Fix: admin menu not visible and some plugin admin not accessible with PHP < 5.5
|
|
||||||
|
|
||||||
Dotclear 2.11 - 2016-12-28
|
|
||||||
===========================================================
|
|
||||||
* 🐘 PHP 5.3+ is required
|
|
||||||
* 🛡 Security : Prevents XSS injection in media title, thanks smarterbitbybit for report
|
|
||||||
* Cope with locale for sorting order if possible (work in progress)
|
|
||||||
* Rich-text-editor (xhtml) may be disabled for Blog/Category description, widget's textareas, …
|
|
||||||
* Add direct access to module's settings from plugins management page (depends on _define.php of modules)
|
|
||||||
* Menus (except favorites) are now lexically sorted (except "new post" item)
|
|
||||||
* Add Entry date as sort order in comments list
|
|
||||||
* Switch admin CSS to Sass/Compass (work in progress)
|
|
||||||
* Add 'l' and 'm' accesskey for editor toolbars, respectively for 'insert link' and 'select media' buttons
|
|
||||||
* Add new categories attribute to EntryIf template tag
|
|
||||||
* Remove Dublin-core metadata from <head> in template-sets
|
|
||||||
* ToolMan (js) not more used, thank's Tim Taylor for all this years together!
|
|
||||||
* Soft redesign of administration pages using responsive font-size and OS system fonts (IE 10+)
|
|
||||||
* Add a user preference to hide additional/secondary information
|
|
||||||
* Add actions on blog list, new sort order: blog status
|
|
||||||
* Update CKEditor to 4.6.1
|
|
||||||
* Open trackbacks with behaviors and add basic Webmention support
|
|
||||||
* Add First Publication mecanism and an option to auto-ping when fired
|
|
||||||
* Berlin theme is now based on Dotty template-set
|
|
||||||
* Move advanced and plugins blog’s prefs in two separate foldable sections
|
|
||||||
* Add legend and title insertion option for image insertion in entry
|
|
||||||
* Some notices and messages may be hidden
|
|
||||||
* Add urls attribute to CategoryIf template tag
|
|
||||||
* CSP: Move admin CSP admin/csp_report.txt to DC_VAR/csp/csp_report.json
|
|
||||||
* CSP: Violations are now stored only once in report if repeated
|
|
||||||
* a11y: Remove empty link (href=#) from admin
|
|
||||||
* Fix: Proxies may use standard HTTP(S) ports and SSL may now run through a proxy
|
|
||||||
* Fix: Prevents precondition failed during activated theme update
|
|
||||||
* 🐛 → Various bugs and typos fixed
|
|
||||||
* 🌼 → A lot of locales and cosmetic adjustments
|
|
||||||
* 🚽 → Housecleaning of no more used scripts, images, resources, IE 9- :-)
|
|
||||||
|
|
||||||
Dotclear 2.10.4 - 2016-11-02
|
|
||||||
===========================================================
|
|
||||||
* PostgreSQL < 9.1 fix
|
|
||||||
|
|
||||||
Dotclear 2.10.3 - 2016-11-01
|
|
||||||
===========================================================
|
|
||||||
* Security: Fix CVE-2016-7903: Password Reset Address Spoof — Thank's Hongkun Zeng for report
|
|
||||||
* Security: Fix CVE-2016-7902: Media Manager, unrestricted File Upload — Thank's Hongkun Zeng for report
|
|
||||||
* CSP: Cope with external sources used in editor's iframe to preview public external content
|
|
||||||
* Fix: Cope with post.post_position field during flat import
|
|
||||||
* Fix: Prevents precondition failed during currently activated theme update
|
|
||||||
* Fix: Remove unecessary header (cope by dotclear) in page plugin
|
|
||||||
* Fix: Let some proxies playing with standard http and https ports
|
|
||||||
* Fix: Let SSL runs through a proxy, it may be ok, sometimes
|
|
||||||
* 🐛 → Various bugs and typos fixed
|
|
||||||
|
|
||||||
Dotclear 2.10.2 - 2016-08-17
|
|
||||||
===========================================================
|
|
||||||
* Update fails with PostgreSQL db support → fixed
|
|
||||||
|
|
||||||
Dotclear 2.10.1 - 2016-08-15
|
|
||||||
===========================================================
|
|
||||||
* CSP (Content-Security-Policies) :
|
|
||||||
* Fix default directive for new installation
|
|
||||||
* Cope with media public URL for media manager
|
|
||||||
* Cope with blog public URL for post/page preview
|
|
||||||
* Codemirror lib is now packed as the other Javascript lib are
|
|
||||||
|
|
||||||
Dotclear 2.10 - 2016-08-13
|
|
||||||
===========================================================
|
|
||||||
* Security: Prevents .htaccess upload, thanks wiswat
|
|
||||||
* Security: Prevents download of a zip media folder outside root media folder, thanks wiswat
|
|
||||||
* Security: Prevents sort of SSRF/XSPA vulnerability in feed import, thanks wiswat
|
|
||||||
* Security: Prevents reflected XSS in meda manager, thanks Chen Ruiqi
|
|
||||||
* Security: Fix somes vulnerabilities in blogroll plugin, thanks Onur Yılmaz - Netsparker (https://www.netsparker.com)
|
|
||||||
* Fix mix-content preview
|
|
||||||
* Pure CSS3 sticky footer for admin pages (aka « footer de merde »)
|
|
||||||
* Add missing breadcrumb styles for blowup theme
|
|
||||||
* Currently logged super-admin may now change it's id wihtout loosing access at next login
|
|
||||||
* The favorites icons may now be hidden from dashboard in user preferences
|
|
||||||
* Number of posts/pages/comments are now displayed at top of lists, including quick filters depending on their status
|
|
||||||
* Search widget has now a placeholder option (HTML5 only)
|
|
||||||
* Add Apache 2.4+ directives in .htaccess
|
|
||||||
* New favorites media folders (displayed at the top of recent folder list) in media manager
|
|
||||||
* New pure HTML5 template set named dotty cloned from currywurst templateset
|
|
||||||
* Codemirror lib updated (2.35.0 → 5.15.2) and moved to core:
|
|
||||||
* 40+ Codemirror themes are available — set in user preferences
|
|
||||||
* Fullscreen mode has been added (F11 switching key)
|
|
||||||
* 3rd party plugins may now load and run it with dcPage::jsLoadCodeMirror() and dcPage::jsRunCodeMirror(), see themeEditor plugin for example
|
|
||||||
* New mark button for legacy editor (HTML5 only)
|
|
||||||
* New with_category attribute for tpl:Entries
|
|
||||||
* Add a /var directory:
|
|
||||||
* Set with DC_VAR constant in inc/config.php
|
|
||||||
* Admin URL of a var file should be retrieve with dcPage::getVF()
|
|
||||||
* Public URL of a var file should be retrieve with dcBlog::getVF()
|
|
||||||
* 3rd party plugins should create their own folder inside /var (aka DC_VAR) to keep it correctly organized
|
|
||||||
* Emails and web site have been added to the comments filters' list
|
|
||||||
* Some columns for posts and pages lists are now optional — set in user preferences
|
|
||||||
* Add Post URL sample in blog parameters
|
|
||||||
* CKEditor lib update (4.5.8 → 4.6.0)
|
|
||||||
* Wiki syntax: new ") <text>" mark to generate aside blocks
|
|
||||||
* CSP (Content Security Policies) have been implemented on admin pages:
|
|
||||||
* settings may be adjusted in system settings / about:config → system (see csp_admin… values)
|
|
||||||
* violation reports will be stored in admin/csp_report.txt (PHP 5.4+ only)
|
|
||||||
* new behaviour adminPageHTTPHeaderCSP may be used by 3rd party to adjust CSP directives
|
|
||||||
* New behaviour adminPageHTTPheaders
|
|
||||||
* New "Go Top" button displayed for long admin pages
|
|
||||||
* 🐛 → Various bugs and typos fixed
|
|
||||||
* 🌼 → Some locales and cosmetic adjustments
|
|
||||||
|
|
||||||
Dotclear 2.9.1 - 2016-03-27
|
|
||||||
===========================================================
|
|
||||||
* Security: Add shtml extension to default media exclusion extension control, thanks Nitin Venkatesh for report
|
|
||||||
* Changing theme is now allowed even with read-only theme folder
|
|
||||||
* Audio media are not more preloaded in media manager pages
|
|
||||||
* Array settings/prefs are stored with 'array' type rather than 'string'
|
|
||||||
* 🐛 → Various bug fixes
|
|
||||||
* 🌼 → Some cosmetic adjustments
|
|
||||||
|
|
||||||
Dotclear 2.9 - 2016-02-29
|
|
||||||
===========================================================
|
|
||||||
* Additionnal menu items are now lexically sorted (default items and favorites order will be preserved)
|
|
||||||
* Wiki syntax : Added ""marked text"" support (HTML5 only)
|
|
||||||
* Session TTL are now adjustable (set DC_SESSION_TTL in inc/config.php)
|
|
||||||
* Add behaviors for posts/pages/comments/users lists' columns → let 3rd party plugin playing with them
|
|
||||||
* Blog and user lists are now lexically sorted
|
|
||||||
* Some new filters have been added for post lists
|
|
||||||
* Add a search engine in media manager (looking in filename, title and description metadata)
|
|
||||||
* Add recent folders direct access mechanism for the media manager (setting in user prefs)
|
|
||||||
* Add a another display mode (list) to the media manager
|
|
||||||
* Details about currently selected thumbnail in media manager are now displayed
|
|
||||||
* Shortcut access to the upload file form is now displayed on top on media page
|
|
||||||
* Default insertion size (width and height) may now be defined for video media
|
|
||||||
* Flash player fallback insertion is now optional for audio and video media
|
|
||||||
* Modules may have dependencies on Dotclear core version too (using 'core' as module name)
|
|
||||||
* Avoid mixed content (http vs https) for post/page preview: will open preview in another window if necessary
|
|
||||||
* Finnish translation has been added
|
|
||||||
* Content-length header is not more sent in HTTP response (should fix very long delays on some servers)
|
|
||||||
* Template engine : add tpl:EntryAuthorEmailMD5 and tpl:EntryCategoryDescription tags
|
|
||||||
* A new pref/setting array type is now available (JSON encoded in db)
|
|
||||||
* Cope with sort of "un-attached" media → allows new features as "featured media" plugin
|
|
||||||
* CKEditor library updated from 4.5.1 to 4.5.8
|
|
||||||
* Update jQuery from 1.11.3 to 2.2.0, jQuery-migrate from 1.2.1 to 1.3.0, jQuery-ui-custom from 1.11.2 to 1.11.4
|
|
||||||
* Provide jQuery 2.2.0 for public use (themes/plugins) - 1.4.2 (default) and 1.11.3 still provided
|
|
||||||
* Some locales added or updated
|
|
||||||
* PHP 7 compliance, PHP 5.3 min
|
|
||||||
* Fix : Cope with "unknown" scheme in url (ie nor http: neither https: is defined in origin url)
|
|
||||||
* Fix : Let select another theme even if theme folder is read-only
|
|
||||||
* Fix : XML-RPC media uploaded are not more twice Base64 decoded
|
|
||||||
* And plenty of other 🐛 🔫, various 🌼 adjustments, and also lot of 🍻 drunk
|
|
||||||
|
|
||||||
Dotclear 2.8.2 - 2015-10-25
|
|
||||||
===========================================================
|
|
||||||
* Security fix : Fixed potential XSS on comments management page
|
|
||||||
* Security fix : Enforce media exclusion control
|
|
||||||
* Php 5.5 leaves NULL chars in unpack ==> add trim, fixed
|
|
||||||
* Media title (in standard mode) is now taken into account on upload
|
|
||||||
* Some 🐛 🔫
|
|
||||||
|
|
||||||
Dotclear 2.8.1 - 2015-09-23
|
|
||||||
===========================================================
|
|
||||||
* Fix admin pager parameters escaping - thanks Keiko Yashiki from JPCERT/CC for reporting this XSS
|
|
||||||
* Error on changing post author in entries' lists: fixed
|
|
||||||
* Cope with unknown URL scheme in X-Frame-Options
|
|
||||||
* One ot two of 🍻 drunk
|
|
||||||
|
|
||||||
Dotclear 2.8 - 2015-08-13
|
|
||||||
===========================================================
|
|
||||||
* New module dependencies system (plugins)
|
|
||||||
* Theme editor: Cope with css theme sub-folder
|
|
||||||
* extension/heritage system applied to mustek templateset
|
|
||||||
* installation wizard now allows SQLite engine
|
|
||||||
* Legacy editor toolbar may now be displayed below textarea
|
|
||||||
* Breadcrumb plugin added to the distribution, included in mustek/currywurst templatesets
|
|
||||||
* Allow a fifth parameter (optional) for image to insert a legend using figure/figcaption tags (wiki)
|
|
||||||
* XHTML validator removed from legacy editor
|
|
||||||
* Update jQuery from 1.11.2 to 1.11.3
|
|
||||||
* Add a blog parameter to disable internal search
|
|
||||||
* Add some sort orders and filters criteria for posts and comments
|
|
||||||
* Update CKEditor from 4.4.8 to 4.5.2
|
|
||||||
* Add IP and antispam filter columns when displaying spams
|
|
||||||
* Add actions to directly blacklist IP from comments list
|
|
||||||
* Lexical sort order for tags and widgets
|
|
||||||
* Use HTML5 audio tag for MP3 attachments
|
|
||||||
* Bye the 🐈, welcome the 🐸
|
|
||||||
* Lot of 🐛 🔫
|
|
||||||
* Various 🌼 adjustments
|
|
||||||
* Full of 🍻 drunk
|
|
||||||
|
|
||||||
Dotclear 2.7.4 - 2015-02-13
|
|
||||||
===========================================================
|
|
||||||
* Berlin theme: resources usage has been optimized
|
|
||||||
* currywurst templateset: head-linkrel block name fixed
|
|
||||||
* Current editor syntax: now displayed near edited field (post/page/quick entry)
|
|
||||||
* Some admin URLs were malformed: fixed
|
|
||||||
* Post/page preview: anti-clickjacking system fixed
|
|
||||||
* The cat is valid now
|
|
||||||
|
|
||||||
Dotclear 2.7.3 - 2015-01-13
|
|
||||||
===========================================================
|
|
||||||
* Restore advanced edition of category description (as in 2.6)
|
|
||||||
* Various bug fixes
|
|
||||||
* Some cosmetic adjustments
|
|
||||||
|
|
||||||
Dotclear 2.7.2 - 2014-12-25
|
|
||||||
===========================================================
|
|
||||||
* Dotclear wiki could not be used by standard user: fixed
|
|
||||||
|
|
||||||
Dotclear 2.7.1 - 2014-12-25
|
|
||||||
===========================================================
|
|
||||||
* Various bug fixes
|
|
||||||
* Some cosmetic adjustments
|
|
||||||
|
|
||||||
Dotclear 2.7 - 2014-12-13
|
|
||||||
===========================================================
|
|
||||||
* Security : protection against clickjacking may be activated (see blog parameters)
|
|
||||||
* Switch to HTML5 : backend, templatesets and themes
|
|
||||||
* ARIA roles in da place (a11y)
|
|
||||||
* Multiple templatesets : mustek (legacy) and currywurst
|
|
||||||
* Themes may use extension/heritage template mechanisms
|
|
||||||
* New theme (Berlin) based on currywurst templateset
|
|
||||||
* New WYSIWYG editor (CKEditor)
|
|
||||||
* Dotclear Wiki now produces HTML5 compatible markup
|
|
||||||
* Video and audio HTML5 tags are now used (with fallback to flash if possible)
|
|
||||||
* Copying default theme to user-defined theme folder is not more necessary
|
|
||||||
* Preview of comment may be optional (see blog parameters)
|
|
||||||
* Widgets may be put offline without deleting them
|
|
||||||
* jQuery version may be choosen between 1.4.2 (default) and 1.11.1 (see blog parameters)
|
|
||||||
* Number of posts listed on home page may be different than other pages (see blog parameters)
|
|
||||||
* Hidden folders are now hidden in media manager (set DC_SHOW_HIDDEN_DIRS to true in config.php to display them)
|
|
||||||
* User-defined template files may be reset (deleted) in theme editor
|
|
||||||
* Drag'n'drop now enabled on touch screens
|
|
||||||
* Alternative syntax may be set for comments by third-party plugins
|
|
||||||
* A lot of bug fixes
|
|
||||||
* Much more cosmetic adjustements and enhancements
|
|
||||||
|
|
||||||
Dotclear 2.6.4 - 2014-08-18
|
|
||||||
===========================================================
|
|
||||||
* Security fix: Sanitize search request. Thanks to Takayuki Uchiyama
|
|
||||||
* Security fix: Strenghened xmlrpc (see http://www.breaksec.com/?p=6362)
|
|
||||||
|
|
||||||
Dotclear 2.6.3 - 2014-05-16
|
|
||||||
===========================================================
|
|
||||||
* Security fix: Strengthened xmlrpc auth. Thanks to Egidio Romano
|
|
||||||
* Security fix: Strengthened categories ordering. Thanks to Egidio Romano
|
|
||||||
|
|
||||||
Dotclear 2.6.2 - 2014-01-20
|
|
||||||
===========================================================
|
|
||||||
* Security fix: Fixed potential code injection on password protected post/page. Thanks to Charlie Briggs
|
|
||||||
* Bugfix: cope with numeric module (plugin/theme) id
|
|
||||||
* Bugfix: Bad SQL syntax when using SQLite
|
|
||||||
* Bugfix: BlogParentThemeURL template value is back
|
|
||||||
* Various bug fixes
|
|
||||||
|
|
||||||
Dotclear 2.6.1 - 2013-11-22
|
|
||||||
===========================================================
|
|
||||||
* Bugfix: trackbacks/pingbacks post URL
|
|
||||||
* Bugfix: short/full list of tags (post edition)
|
|
||||||
* Bugfix: Toolbar not drawn on new comment form (administration)
|
|
||||||
* Various bug fixes
|
|
||||||
* Some cosmetic adjustments
|
|
||||||
|
|
||||||
Dotclear 2.6 - 2013-11-13
|
|
||||||
===========================================================
|
|
||||||
* Various bug fixes
|
|
||||||
* Various cosmetic adjustments
|
|
||||||
|
|
||||||
Dotclear 2.6-RC - 2013-10-18
|
|
||||||
===========================================================
|
|
||||||
* PHP 5.2 required
|
|
||||||
* jQuery upgraded to 1.10.2 (including jQuery migrate plugin 1.2.1)
|
|
||||||
* mySQLi support (now proposed by default rather than mySQL)
|
|
||||||
* Administration revamped, relooked, redesigned, new icons, new ergonomic's behaviours
|
|
||||||
* Administration is now responsive (easier to cope with it on small devices)
|
|
||||||
* Administration menu re-organized
|
|
||||||
* a11y (accessibility) everywhere, with and whithout Js
|
|
||||||
* Success, notice and warning messages have been harmonized
|
|
||||||
* daInstaller has been dispatched in core (in plugins and blog themes management)
|
|
||||||
* Global help is now available, contextual help is available on every page
|
|
||||||
* Media manager enhanced
|
|
||||||
* Maintenance plugin revamped and enhanced (now includes export features)
|
|
||||||
* Categories management enhanced
|
|
||||||
* Plugins and themes management revamped
|
|
||||||
* New “Plumetis” variation for Blowup theme
|
|
||||||
* Jasmine is now used for unit testing of js components
|
|
||||||
* A lot of bug fixes
|
|
||||||
* A lot of cosmetics adjustments
|
|
||||||
* A lot of enhancements
|
|
||||||
|
|
||||||
Dotclear 2.5.3 - 2013-09-13
|
|
||||||
===========================================================
|
|
||||||
* Bugfix: l10n Clearbricks library
|
|
||||||
* Bugfix: post's comments and trackbacks counters
|
|
||||||
* Check public and cache directories (existence and permissions)
|
|
||||||
* Avoid Categorie's identical URL as far as possible
|
|
||||||
* Cope with alpha layers in PNG images for thumbnails generation
|
|
||||||
* Add password strength indicators
|
|
||||||
* Fix permission form (checkboxes management)
|
|
||||||
* Better management of antispam filters
|
|
||||||
* Minor enhancements
|
|
||||||
* Various bug fixes
|
|
||||||
* Various cosmetic adjustments
|
|
||||||
|
|
||||||
Dotclear 2.5.2 - 2013-08-14
|
|
||||||
===========================================================
|
|
||||||
* Security fix: Fixed potential XSS
|
|
||||||
* Bugfix: l10n Clearbricks library
|
|
||||||
* <tpl:LoopPosition> now works <tpl:Attachments>
|
|
||||||
* Dotclear update check may now be forced (ignoring cache)
|
|
||||||
* Enforce integration of daInstaller plugin
|
|
||||||
* Tags link button is now available on page editor
|
|
||||||
* Default cache age is now 1 week instead of 2 hours
|
|
||||||
* Quick entry dashboard module is not activated by default on new installation
|
|
||||||
* New template {{tpl:BlogParentThemeURL}} (return URL of parent theme of blog's theme if any, URL of blog's theme otherwise)
|
|
||||||
* Fix post comments number on comments deletion
|
|
||||||
* Fix order of backup files
|
|
||||||
* Minor enhancements
|
|
||||||
* Various bug fixes
|
|
||||||
* Various cosmetic adjustments
|
|
||||||
|
|
||||||
Dotclear 2.5.1 - 2013-07-20
|
|
||||||
===========================================================
|
|
||||||
* Security fix: Replacement of swfupload.swf by a jQuery plugin
|
|
||||||
* Security enhancement: Strenghened lists display
|
|
||||||
* Thumbnails quality improved
|
|
||||||
* Minor enhancements
|
|
||||||
* Various bug fixes
|
|
||||||
* Various cosmetic adjustments
|
|
||||||
|
|
||||||
Dotclear 2.5.0 - 2013-03-12
|
|
||||||
===========================================================
|
|
||||||
* Security fix: XSS vulnerabilities in swfupload.swf (media enhanced uploader)
|
|
||||||
* Ductile theme may now use webfont (from Google, Adobe and similar providers)
|
|
||||||
* daInstaller plugin is now included in the official distribution
|
|
||||||
* The media enhanced uploader may now be temporarily enabled or disabled
|
|
||||||
* Add mass expand on posts and comments lists
|
|
||||||
* Allow wildcard for IP address on comments filters
|
|
||||||
* Add ability to delete non empty category (and move its content to another category)
|
|
||||||
* Every types of entries may be used to inserted an entry link in current edited post
|
|
||||||
* Add (none) option to image insertion title pattern
|
|
||||||
* Smileys are not more converted in image in pre,code,kbd,script and math contents
|
|
||||||
* Notes' title can be now enclosed in h4 (default), h3 or p HTML tag
|
|
||||||
* Now display translated name and desc of plugins
|
|
||||||
* Add publication date validation on post and page editing forms
|
|
||||||
* Add description to widgets
|
|
||||||
* Add syntax color option to theme editor plugin
|
|
||||||
* Add delete button on media item page
|
|
||||||
* Add/complement display modes (all pages, home page only, except on home page) for all widgets
|
|
||||||
* {{tpl:Widgets}} without type attribute set displays now all widgets (from nav, extra and custom)
|
|
||||||
* Add {{tpl:else}}, {{tpl:TagCount}}, <tpl:TagIf>, {{tpl:CategoryEntriesCount}} template tags
|
|
||||||
* Add cat_only, no_tag and content_only attributes to {{tpl:EntryFirstImage}} tag
|
|
||||||
* Add capitalize attribute to template filters' list
|
|
||||||
* Enhance links lookup anti spam filter
|
|
||||||
* Add hidden optional attribute for pages
|
|
||||||
* Adaptative compression rate for thumbnails generation
|
|
||||||
* Add timestamp on admin information messages
|
|
||||||
* Update to jQuery 1.8.3 and jQuery-UI 1.9.2 (custom)
|
|
||||||
* Add default favicon.ico
|
|
||||||
* Add default attributes settings for image,mp3,flv insertion
|
|
||||||
* Various bug fixes
|
|
||||||
* Various cosmetic updates and contrast adjustments
|
|
||||||
|
|
||||||
Dotclear 2.4.4 - 2012-08-13
|
|
||||||
===========================================================
|
|
||||||
* Bugfix: Programmed entries works again.
|
|
||||||
* Compatibility fix: widgets are now fully php >=5.3 compliant
|
|
||||||
* Security fix: potential CSRF in user management
|
|
||||||
* has_tag now part of dotclear core, moved from tag plugin.
|
|
||||||
* empty title fixed on rss reader widget
|
|
||||||
|
|
||||||
Dotclear 2.4.3 - 2012-05-18
|
|
||||||
===========================================================
|
|
||||||
* Admin: My favorites menu can be hidden
|
|
||||||
* Admin: Fix wordpress importer
|
|
||||||
* Admin: about:config and user:pref tables are now more readable
|
|
||||||
* Ductile theme: Blog logo can be changed
|
|
||||||
* New lithuanian language (thanks to Paulius Černakauskas)
|
|
||||||
* Various bug fixes
|
|
||||||
|
|
||||||
Dotclear 2.4.2 - 2012-02-11
|
|
||||||
===========================================================
|
|
||||||
* Security fix release
|
|
||||||
* 4 XSS vulnerabilities fixed, discovered by High-Tech Bridge
|
|
||||||
|
|
||||||
Dotclear 2.4.1.2 - 2011-12-24
|
|
||||||
===========================================================
|
|
||||||
* Happy Christmas!
|
|
||||||
* Security: fixed one SQL injection vulnerability in Clearbricks, thanks to Adjaya
|
|
||||||
* New behaviour: publicGetURLFor
|
|
||||||
* New behaviour: publicRegisterURL
|
|
||||||
* New behaviour: templatePrepareParams
|
|
||||||
* Changed the way to get artefacts URLs, through $core->url->getURLFor calls, instead of $core->url->getBase()
|
|
||||||
* new/updated parameter sql_only in $core->blog->getPosts and $core->blog->getComments
|
|
||||||
|
|
||||||
Dotclear 2.4.0 - 2011-11-13
|
|
||||||
===========================================================
|
|
||||||
* Admin: new iconset from Thomas Daveluy
|
|
||||||
* Admin: Accessibility enhancements
|
|
||||||
* Added a custom widget sidebar
|
|
||||||
* Added a new theme (Ductile)
|
|
||||||
* Added a new plugin (simpleMenu)
|
|
||||||
* handling of postgres non default schemas (db_prefix = 'schema.prefix')
|
|
||||||
* New iconset mechanism
|
|
||||||
* New behaviour: coreBlogBeforeGetPosts
|
|
||||||
* Security fix: Spam comments feed now checks for blog permission. Thanks to Romuald Brunet.
|
|
||||||
* Various bug fixes
|
|
||||||
|
|
||||||
Dotclear 2.3.1 - 2011-06-14
|
|
||||||
===========================================================
|
|
||||||
* Updated makefile for cleaner distrib.
|
|
||||||
* Better localization handling for prefs and shortcuts.
|
|
||||||
* Misc JS & CSS cleaning.
|
|
||||||
* Import/Export preferences-related bugfix.
|
|
||||||
* Administrative mail address is now configurable.
|
|
||||||
* Security: one minor fix and changes for two potential problems. Thanks to Jeremie Boutoille
|
|
||||||
|
|
||||||
Dotclear 2.3.0 - 2011-05-16
|
|
||||||
===========================================================
|
|
||||||
* Admin: Major backend redesign
|
|
||||||
* Admin: Customizable Dashboard
|
|
||||||
* Admin: New Favourites admin submenu
|
|
||||||
* Admin: New user preferences backend
|
|
||||||
* Admin: Accessibility enhancements
|
|
||||||
* Admin: Inline help extended
|
|
||||||
* Templates: Default theme templates moved to inc/public/default-templates
|
|
||||||
* Clearbricks: External libraries relocated to inc/libs
|
|
||||||
* Clearbricks: fixed utf-8 and mysql strict mode problems
|
|
||||||
* Added a safe mode connection, disabling all plugins
|
|
||||||
* Mysqli support (config.php may need to be updated manually)
|
|
||||||
* Fixed dcLog bug with pgsql
|
|
||||||
* Fixed comment/trackbacks counters reset.
|
|
||||||
* Several other bug fixes
|
|
||||||
|
|
||||||
|
|
||||||
Dotclear 2.2.3 - 2011-04-01
|
|
||||||
===========================================================
|
|
||||||
* Security fix in media manager. Thx to Raphaël
|
|
||||||
* Bugfix : 2.2.2 was preventing manual thumbnail regeneration.
|
|
||||||
* Database handling bugfixes
|
|
||||||
|
|
||||||
Dotclear 2.2.2 - 2011-01-17
|
|
||||||
===========================================================
|
|
||||||
* Bugfix: 2.2.1 was blocking new installations
|
|
||||||
* Autoupdate procedure should now be "bad ftp client configuration"-proof.
|
|
||||||
* Several other small bugfixes
|
|
||||||
|
|
||||||
Dotclear 2.2.1 - 2011-01-15
|
|
||||||
===========================================================
|
|
||||||
* ExternalMedia is not part of the core distribution anymore
|
|
||||||
* New attribute to tpl:SysIf: blog_id
|
|
||||||
* New behaviour: adminMediaItemForm
|
|
||||||
* Several bugfixes
|
|
||||||
* Several code optimizations
|
|
||||||
* Several typos corrected
|
|
||||||
* Security fix in Clearbricks. Thx to François Pierre-Doray for pointing it out.
|
|
||||||
|
|
||||||
Dotclear 2.2 - 2010-07-01
|
|
||||||
===========================================================
|
|
||||||
* New installation wizard.
|
|
||||||
* Several new behaviours:
|
|
||||||
- adminCommentHeaders
|
|
||||||
- adminCommentsActionsCombo
|
|
||||||
- adminCommentsActions
|
|
||||||
- adminCommentsActionsContent
|
|
||||||
- adminBeforeCommentDelete
|
|
||||||
- adminPostsActionsHeaders
|
|
||||||
- adminUsersActionsCombo
|
|
||||||
- coreBeforeCategoryCreate & coreAfterCategoryCreate
|
|
||||||
- coreBeforeCategoryUpdate & coreAfterCategoryUpdate
|
|
||||||
- coreBeforeLogCreate & coreAfterLogCreate
|
|
||||||
- coreBeforePostCreate & coreAfterPostCreate
|
|
||||||
- coreBeforePostUpdate & coreAfterPostUpdate
|
|
||||||
- coreMediaConstruct
|
|
||||||
- templateCustomSortByAlias
|
|
||||||
- urlHandlerGetArgsDocument
|
|
||||||
* New methods for several core classes.
|
|
||||||
* Metadata integration to the core.
|
|
||||||
* Error handlers can now be extended.
|
|
||||||
* Templates: blocks can now be recursive.
|
|
||||||
* Templates: Entries & Comments tags can now be sorted.
|
|
||||||
* Templates: The template subsystem is quicker, linier, and ready to be extended.
|
|
||||||
* Complete reworking of the settings system
|
|
||||||
* Correct handling of postgresql non default schemas.
|
|
||||||
* Admin: Autocompletion and further enhancing to tags handling.
|
|
||||||
* Admin: Accessibility & ergonomic tweaks.
|
|
||||||
* Admin: Administrator tag in users list.
|
|
||||||
* Comment cookies are now specific to the blog rather than to the domain.
|
|
||||||
* Password changes can now be mandatory.
|
|
||||||
* jQuery updated to 1.4.2.
|
|
||||||
* And way too many bugfixes and typos squashes to be listed.
|
|
||||||
|
|
||||||
|
|
||||||
Dotclear 2.1.7 - 2010-05-25
|
|
||||||
===========================================================
|
|
||||||
* Auto-update procedure fix
|
|
||||||
|
|
||||||
Dotclear 2.1.6 - 2009-10-01
|
|
||||||
===========================================================
|
|
||||||
* Install procedure fixes
|
|
||||||
* Admin: Page managers can now create pages
|
|
||||||
* Admin: several typos corrected.
|
|
||||||
* Admin: Widgets now work in IE8.
|
|
||||||
* Admin: Password protected posts can now be previewed.
|
|
||||||
* Templates: tpl:Meta* are now tpl:Tags*.
|
|
||||||
* Templates: <tpl:Entries lastn="0"> now display all posts.
|
|
||||||
* new behavior: adminPageHTMLHead
|
|
||||||
* DB schema: new blog_id field in log table
|
|
||||||
* Media manager: Pubic folder can now be set on a different host.
|
|
||||||
* WordPress import fixes
|
|
||||||
* Dailymotion insertion fix
|
|
||||||
* Upgrade procedure: CRLF removed in files that were bugging the upgrade.
|
|
||||||
* JQuery updated to 1.3
|
|
||||||
* IE7-js update
|
|
||||||
* security: Full Path Disclosure protection. Thx to Karim Ayad for pointing it out.
|
|
||||||
* and way too many bugfixes to be listed.
|
|
||||||
|
|
||||||
Dotclear 2.1.5 - 2009-02-05
|
|
||||||
===========================================================
|
|
||||||
* Security release
|
|
||||||
* Youtube insertion update
|
|
||||||
|
|
||||||
Dotclear 2.1.4 - 2008-12-21
|
|
||||||
===========================================================
|
|
||||||
* Security flaw fix
|
|
||||||
* WordPress import refining
|
|
||||||
* XML-RPC improvements
|
|
||||||
|
|
||||||
Dotclear 2.1.3 - 2008-11-19
|
|
||||||
===========================================================
|
|
||||||
* Admin: New upgrade procedure
|
|
||||||
* Admin: Fixed video insertion bug
|
|
||||||
* Template: New attributes
|
|
||||||
* url on EntryIf
|
|
||||||
* only_category on Blogroll
|
|
||||||
* no_context on Pagination
|
|
||||||
* Template: New tag
|
|
||||||
* BlogID
|
|
||||||
* Admin: escaped blog_id on authentication page
|
|
||||||
|
|
||||||
Dotclear 2.1.1 - 2008-11-07
|
|
||||||
===========================================================
|
|
||||||
* Admin: Automatic Update bug fixes
|
|
||||||
* Admin: Disable Automatic Update if no digests file
|
|
||||||
* Admin: Javascript fixes in authentication page
|
|
||||||
* Admin: Fixed errors with categories select boxes
|
|
||||||
* Template: Added level attribute in tpl:Categories
|
|
||||||
* Media: Added H.264/MPEG-4 AVC for mp4 files
|
|
||||||
|
|
||||||
Dotclear 2.1 - 2008-11-01
|
|
||||||
===========================================================
|
|
||||||
* Subcategories
|
|
||||||
* Admin: Automatic Update
|
|
||||||
* Admin: Flash 10 support for uploader
|
|
||||||
* Admin: mailto link in comment details
|
|
||||||
* Admin: Embedded video size selection
|
|
||||||
* Admin: Restrict session cookie path to admin
|
|
||||||
* Media: H.264/MPEG-4 AVC (HD) support with m4v files
|
|
||||||
* Inherited themes
|
|
||||||
* WordPress XML-RPC methods support
|
|
||||||
* True unicode URLs
|
|
||||||
* Plugin: Widgets as template tags
|
|
||||||
* Plugin: Filters in entries widgets and Blogroll
|
|
||||||
* Plugin: Added vimeo.com in external media
|
|
||||||
* Template: New tags
|
|
||||||
* LoopPosition
|
|
||||||
* CommentAuthorDomain
|
|
||||||
* CommentAuthorMD5
|
|
||||||
* EntryFirstImage
|
|
||||||
* EntryCategoryShortURL
|
|
||||||
* CategoryIf
|
|
||||||
* CategoryFirstChildren
|
|
||||||
* CategoryParents
|
|
||||||
* EntryCategoriesBreadcrum
|
|
||||||
* MediaURL
|
|
||||||
|
|
||||||
Dotclear 2.0.2 - 2008-09-05
|
|
||||||
===========================================================
|
|
||||||
* New installation procedure
|
|
||||||
* Plugin: WordPress import fixes
|
|
||||||
* Plugin: Plain text export as downloadable files
|
|
||||||
* Plugin: Message about URLs in Dotclear 1.2 import
|
|
||||||
* Public: Display a message if search returns no result
|
|
||||||
* Admin: Fixed some CSS bugs
|
|
||||||
* Admin: Batch select/unselect entries
|
|
||||||
* Admin: In a media item, find entries containing it
|
|
||||||
|
|
||||||
Dotclear 2.0.1 - 2008-08-16
|
|
||||||
===========================================================
|
|
||||||
* Plugin: Fixed a bug with Dotclear 1.2 URLs import.
|
|
||||||
* Plugin: Fixed a l10n bug in Pages
|
|
||||||
* Admin: Enhanced plugins resources loading and cache
|
|
||||||
|
|
||||||
Dotclear 2.0 - 2008-08-01
|
|
||||||
===========================================================
|
|
||||||
* Public: Atom becomes the default feed format. RSS 2 is always available.
|
|
||||||
* Admin: design enhancements and new Dotclear logo
|
|
||||||
* Admin: entries preview in blog context
|
|
||||||
* L10N: New language manager with zip files support
|
|
||||||
* Plugin: Import/Export plugin version 2.0 with import from Dotclear 1.2 and WordPress
|
|
||||||
* Plugin: Pages enhancements (preview, sorting)
|
|
||||||
* Plugin: support for jamendo and deezer in External Media
|
|
||||||
* JSMin on JavaScript files instead of JS packing
|
|
||||||
* SQLite 3 only support (PDO based)
|
|
||||||
* Many bug fixes and major performances improvements
|
|
||||||
|
|
||||||
Dotclear 2.0 RC2 - 2008-06-21
|
|
||||||
===========================================================
|
|
||||||
* FairTrackback spam filter
|
|
||||||
* Language pack infrastructure
|
|
||||||
* Bug fix on comment search with author "0"
|
|
||||||
* Javascript fixes
|
|
||||||
* dcAuth::sessionExists and dcAuth::checkSession new methods
|
|
||||||
* Right management in dcAuth::sudo
|
|
||||||
* Media File sorting options in media manager
|
|
||||||
* CandyUpload, new uploader tool based on SWFUpload
|
|
||||||
* New search engine robots options
|
|
||||||
* New image options
|
|
||||||
* L10N: Japanese and Portugues (Brazil) language packs
|
|
||||||
* Many bug fixes and enhancements
|
|
||||||
|
|
||||||
Dotclear 2.0 RC1 - 2008-05-01
|
|
||||||
===========================================================
|
|
||||||
* New: Pages plugin
|
|
||||||
* New: Theme editor plugin
|
|
||||||
* Entries: Text and WYSIWYG enhancements
|
|
||||||
* Entries: Markup validator
|
|
||||||
* Entries: Insertion of links to other entries from toolbar
|
|
||||||
* Entries: External media insertion (dailymotion, youtube, google video)
|
|
||||||
* Tags: Same list for new and existing entries
|
|
||||||
* Tags: Tags can be removed on all associated entries
|
|
||||||
* Tags: Tags can be removed on a post selection
|
|
||||||
* Admin: Ask password for user management tasks, theme upload and plugin upload
|
|
||||||
* Admin: New contextual help viewer
|
|
||||||
* Media manager: Recreate thumbnails option
|
|
||||||
* Media manager: Custom medium thumbnail size (per blog)
|
|
||||||
* Media manager: Zip files extract support
|
|
||||||
* Media manager: Zip file download of directory
|
|
||||||
* Media manager: File exclusion pattern option
|
|
||||||
* Themes and plugins: Zip as new package format
|
|
||||||
* Themes and plugins: Upload
|
|
||||||
* Themes and plugins: Upgrade within administration interface
|
|
||||||
* Themes and plugins: Deletion
|
|
||||||
* Public: New default theme: Blowup (fully customizable)
|
|
||||||
* Public: Changed the way commenter cookie is handled
|
|
||||||
* Themes: Template files moved to tpl/ directory
|
|
||||||
* L10N: Polish, Catalan and Spanish translations
|
|
||||||
* Misc: jQuery upgraded to 1.2.3
|
|
||||||
* Misc: Crushed png files
|
|
||||||
* Fixed many bugs
|
|
||||||
|
|
||||||
Dotclear 2.0 beta 7 - 2007-07-12
|
|
||||||
===========================================================
|
|
||||||
* New way to display comments and trackbacks on entries in backend
|
|
||||||
* Dashboard visual improvements
|
|
||||||
* Default cache dir created by installation process
|
|
||||||
* Option to limit posts and comments in feeds
|
|
||||||
* Introduced UDBS for installation and upgrade
|
|
||||||
* Changed handling of XML-RPC URLs
|
|
||||||
* New option to force HTTPS redirect if wanted
|
|
||||||
* Enforced cookies security (directory and ssl support)
|
|
||||||
* Added Plugin auto-install and auto-upgrade support
|
|
||||||
* Added trackbacks ttl and moderation preferences
|
|
||||||
* Added an Internal search engine
|
|
||||||
* FLV support in backend with Neolao player
|
|
||||||
* Added nice messages if database is broken or Dotclear not installed
|
|
||||||
* upgrade jQuery to 1.1.3
|
|
||||||
* Fixed many bugs
|
|
||||||
* Fixed security issues in backend
|
|
||||||
|
|
||||||
Dotclear 2.0 beta 6 - 2007-02-19
|
|
||||||
===========================================================
|
|
||||||
* New antispam plugin, with a set of filters (rbl, ipblacklist, spamwords, akismet)
|
|
||||||
* New admin dashboard page
|
|
||||||
* Fixed unwanted logout bug
|
|
||||||
* Added settings to disable template caching and allow PHP code
|
|
||||||
* Blog preferences panel bug fix
|
|
||||||
* New XML-RPC Client and Server
|
|
||||||
* Comment posting permissions bug fix
|
|
||||||
|
|
||||||
Dotclear 2.0 beta 5.4 - 2007-01-19
|
|
||||||
===========================================================
|
|
||||||
* Minor change on spam display in comments.php
|
|
||||||
* Command line upgrade script and fix in load_plugin_file.php
|
|
||||||
* Make akismet configurable only by superadmin with DC_AKISMET_SUPER
|
|
||||||
* SQL optimisations
|
|
||||||
* New comments view in post
|
|
||||||
|
|
||||||
Dotclear 2.0 beta 5.2 - 2007-01-11
|
|
||||||
===========================================================
|
|
||||||
* Fixed a bug with imageMeta::getMeta
|
|
||||||
* Enhanced dynamic file uploader
|
|
||||||
* Move clearbricks files to their own repository
|
|
||||||
* Fixed a bug with auto_br in wikiSimpleComment
|
|
||||||
* Support for language restriction in feeds
|
|
||||||
* Default theme structure changes
|
|
||||||
* Fixed a PHP 5.0 compatibility issue
|
|
||||||
* Installation Wizard
|
|
||||||
|
|
||||||
Dotclear 2.0 beta 4 - 2006-12-26
|
|
||||||
===========================================================
|
|
||||||
* Performances enhancements.
|
|
||||||
* Administration UI enhancements.
|
|
||||||
* More user-friendly Widgets (version 1.5).
|
|
||||||
* Switch to jQuery <http://jquery.com>.
|
|
||||||
* Added jQuery in default theme.
|
|
||||||
* Major changes in HTTP client and Feed Parser based on a
|
|
||||||
generic socket handler.
|
|
||||||
* PHP 5.2 compatibility.
|
|
||||||
* Code documentation (all core and most of clearbricks).
|
|
||||||
* Many bug fixes.
|
|
||||||
|
|
||||||
Dotclear 2.0 beta 3 - 2006-11-05
|
|
||||||
===========================================================
|
|
||||||
* Disallow special wrappers for fopen like functions.
|
|
||||||
* XML/RPC improvements.
|
|
||||||
* Read IPTC and EXIF metadata in uploaded pictures.
|
|
||||||
* MySQL 4.1 support only.
|
|
||||||
* Metadata import from Dotclear 1.2.x.
|
|
||||||
* Akismet plugin.
|
|
||||||
* Pings plugin.
|
|
||||||
* Added a priority setting for plugins.
|
|
||||||
* Many bug fixes.
|
|
||||||
|
|
||||||
Dotclear 2.0 beta 2 - 2006-08-09
|
|
||||||
===========================================================
|
|
||||||
* DC_PLUGIN_ROOT can handle more than one path.
|
|
||||||
* OPML/XBEL import in blogroll plugin.
|
|
||||||
* Fixed a security issue in html::absoluteURLs().
|
|
||||||
* Fixed issues with timezone on scheduled entries.
|
|
||||||
* Multiple categories selection in tpl:Entries.
|
|
||||||
* Improved dbLayer.
|
|
||||||
* Changed category feed URL.
|
|
||||||
* Feeds for tags (entries and comments).
|
|
||||||
* Added attachments count on backend and frontend.
|
|
||||||
* New settings code design. Can now handle wide system settings.
|
|
||||||
* Memory usage improvements with autoloader.
|
|
||||||
* Some code cleanup.
|
|
||||||
* Feed parser improvements.
|
|
||||||
* Themes can be configured if needed.
|
|
||||||
* XMP support on JPEG files.
|
|
||||||
* Media manager improvements.
|
|
||||||
* Spamplemousse now uses DNSBL (and the guy who left the bug was fired).
|
|
||||||
* Javascript editor and toolbar improvements.
|
|
||||||
* RDS support (XML/RPC API discovery).
|
|
||||||
* Added a theme with user stylesheet.
|
|
||||||
* Plugins manager
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
# 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)
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
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.
|
|
||||||
@ -1,339 +0,0 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 2, June 1991
|
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
License is intended to guarantee your freedom to share and change free
|
|
||||||
software--to make sure the software is free for all its users. This
|
|
||||||
General Public License applies to most of the Free Software
|
|
||||||
Foundation's software and to any other program whose authors commit to
|
|
||||||
using it. (Some other Free Software Foundation software is covered by
|
|
||||||
the GNU Lesser General Public License instead.) You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
this service if you wish), that you receive source code or can get it
|
|
||||||
if you want it, that you can change the software or use pieces of it
|
|
||||||
in new free programs; and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
anyone to deny you these rights or to ask you to surrender the rights.
|
|
||||||
These restrictions translate to certain responsibilities for you if you
|
|
||||||
distribute copies of the software, or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must give the recipients all the rights that
|
|
||||||
you have. You must make sure that they, too, receive or can get the
|
|
||||||
source code. And you must show them these terms so they know their
|
|
||||||
rights.
|
|
||||||
|
|
||||||
We protect your rights with two steps: (1) copyright the software, and
|
|
||||||
(2) offer you this license which gives you legal permission to copy,
|
|
||||||
distribute and/or modify the software.
|
|
||||||
|
|
||||||
Also, for each author's protection and ours, we want to make certain
|
|
||||||
that everyone understands that there is no warranty for this free
|
|
||||||
software. If the software is modified by someone else and passed on, we
|
|
||||||
want its recipients to know that what they have is not the original, so
|
|
||||||
that any problems introduced by others will not reflect on the original
|
|
||||||
authors' reputations.
|
|
||||||
|
|
||||||
Finally, any free program is threatened constantly by software
|
|
||||||
patents. We wish to avoid the danger that redistributors of a free
|
|
||||||
program will individually obtain patent licenses, in effect making the
|
|
||||||
program proprietary. To prevent this, we have made it clear that any
|
|
||||||
patent must be licensed for everyone's free use or not licensed at all.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License applies to any program or other work which contains
|
|
||||||
a notice placed by the copyright holder saying it may be distributed
|
|
||||||
under the terms of this General Public License. The "Program", below,
|
|
||||||
refers to any such program or work, and a "work based on the Program"
|
|
||||||
means either the Program or any derivative work under copyright law:
|
|
||||||
that is to say, a work containing the Program or a portion of it,
|
|
||||||
either verbatim or with modifications and/or translated into another
|
|
||||||
language. (Hereinafter, translation is included without limitation in
|
|
||||||
the term "modification".) Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running the Program is not restricted, and the output from the Program
|
|
||||||
is covered only if its contents constitute a work based on the
|
|
||||||
Program (independent of having been made by running the Program).
|
|
||||||
Whether that is true depends on what the Program does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Program's
|
|
||||||
source code as you receive it, in any medium, provided that you
|
|
||||||
conspicuously and appropriately publish on each copy an appropriate
|
|
||||||
copyright notice and disclaimer of warranty; keep intact all the
|
|
||||||
notices that refer to this License and to the absence of any warranty;
|
|
||||||
and give any other recipients of the Program a copy of this License
|
|
||||||
along with the Program.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy, and
|
|
||||||
you may at your option offer warranty protection in exchange for a fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Program or any portion
|
|
||||||
of it, thus forming a work based on the Program, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) You must cause the modified files to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
b) You must cause any work that you distribute or publish, that in
|
|
||||||
whole or in part contains or is derived from the Program or any
|
|
||||||
part thereof, to be licensed as a whole at no charge to all third
|
|
||||||
parties under the terms of this License.
|
|
||||||
|
|
||||||
c) If the modified program normally reads commands interactively
|
|
||||||
when run, you must cause it, when started running for such
|
|
||||||
interactive use in the most ordinary way, to print or display an
|
|
||||||
announcement including an appropriate copyright notice and a
|
|
||||||
notice that there is no warranty (or else, saying that you provide
|
|
||||||
a warranty) and that users may redistribute the program under
|
|
||||||
these conditions, and telling the user how to view a copy of this
|
|
||||||
License. (Exception: if the Program itself is interactive but
|
|
||||||
does not normally print such an announcement, your work based on
|
|
||||||
the Program is not required to print an announcement.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Program,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Program, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Program.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Program
|
|
||||||
with the Program (or with a work based on the Program) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may copy and distribute the Program (or a work based on it,
|
|
||||||
under Section 2) in object code or executable form under the terms of
|
|
||||||
Sections 1 and 2 above provided that you also do one of the following:
|
|
||||||
|
|
||||||
a) Accompany it with the complete corresponding machine-readable
|
|
||||||
source code, which must be distributed under the terms of Sections
|
|
||||||
1 and 2 above on a medium customarily used for software interchange; or,
|
|
||||||
|
|
||||||
b) Accompany it with a written offer, valid for at least three
|
|
||||||
years, to give any third party, for a charge no more than your
|
|
||||||
cost of physically performing source distribution, a complete
|
|
||||||
machine-readable copy of the corresponding source code, to be
|
|
||||||
distributed under the terms of Sections 1 and 2 above on a medium
|
|
||||||
customarily used for software interchange; or,
|
|
||||||
|
|
||||||
c) Accompany it with the information you received as to the offer
|
|
||||||
to distribute corresponding source code. (This alternative is
|
|
||||||
allowed only for noncommercial distribution and only if you
|
|
||||||
received the program in object code or executable form with such
|
|
||||||
an offer, in accord with Subsection b above.)
|
|
||||||
|
|
||||||
The source code for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For an executable work, complete source
|
|
||||||
code means all the source code for all modules it contains, plus any
|
|
||||||
associated interface definition files, plus the scripts used to
|
|
||||||
control compilation and installation of the executable. However, as a
|
|
||||||
special exception, the source code distributed need not include
|
|
||||||
anything that is normally distributed (in either source or binary
|
|
||||||
form) with the major components (compiler, kernel, and so on) of the
|
|
||||||
operating system on which the executable runs, unless that component
|
|
||||||
itself accompanies the executable.
|
|
||||||
|
|
||||||
If distribution of executable or object code is made by offering
|
|
||||||
access to copy from a designated place, then offering equivalent
|
|
||||||
access to copy the source code from the same place counts as
|
|
||||||
distribution of the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
4. You may not copy, modify, sublicense, or distribute the Program
|
|
||||||
except as expressly provided under this License. Any attempt
|
|
||||||
otherwise to copy, modify, sublicense or distribute the Program is
|
|
||||||
void, and will automatically terminate your rights under this License.
|
|
||||||
However, parties who have received copies, or rights, from you under
|
|
||||||
this License will not have their licenses terminated so long as such
|
|
||||||
parties remain in full compliance.
|
|
||||||
|
|
||||||
5. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Program or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Program (or any work based on the
|
|
||||||
Program), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Program or works based on it.
|
|
||||||
|
|
||||||
6. Each time you redistribute the Program (or any work based on the
|
|
||||||
Program), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute or modify the Program subject to
|
|
||||||
these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties to
|
|
||||||
this License.
|
|
||||||
|
|
||||||
7. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Program at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Program by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Program.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under
|
|
||||||
any particular circumstance, the balance of the section is intended to
|
|
||||||
apply and the section as a whole is intended to apply in other
|
|
||||||
circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system, which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
8. If the distribution and/or use of the Program is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Program under this License
|
|
||||||
may add an explicit geographical distribution limitation excluding
|
|
||||||
those countries, so that distribution is permitted only in or among
|
|
||||||
countries not thus excluded. In such case, this License incorporates
|
|
||||||
the limitation as if written in the body of this License.
|
|
||||||
|
|
||||||
9. The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
|
||||||
specifies a version number of this License which applies to it and "any
|
|
||||||
later version", you have the option of following the terms and conditions
|
|
||||||
either of that version or of any later version published by the Free
|
|
||||||
Software Foundation. If the Program does not specify a version number of
|
|
||||||
this License, you may choose any version ever published by the Free Software
|
|
||||||
Foundation.
|
|
||||||
|
|
||||||
10. If you wish to incorporate parts of the Program into other free
|
|
||||||
programs whose distribution conditions are different, write to the author
|
|
||||||
to ask for permission. For software which is copyrighted by the Free
|
|
||||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
|
||||||
make exceptions for this. Our decision will be guided by the two goals
|
|
||||||
of preserving the free status of all derivatives of our free software and
|
|
||||||
of promoting the sharing and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
|
||||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
|
||||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
|
||||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
|
||||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
|
||||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
|
||||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
|
||||||
REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
|
||||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
|
||||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
|
||||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
|
||||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
|
||||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
|
||||||
POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
convey the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program is interactive, make it output a short notice like this
|
|
||||||
when it starts in an interactive mode:
|
|
||||||
|
|
||||||
Gnomovision version 69, Copyright (C) year name of author
|
|
||||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, the commands you use may
|
|
||||||
be called something other than `show w' and `show c'; they could even be
|
|
||||||
mouse-clicks or menu items--whatever suits your program.
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or your
|
|
||||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
|
||||||
necessary. Here is a sample; alter the names:
|
|
||||||
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
|
||||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1989
|
|
||||||
Ty Coon, President of Vice
|
|
||||||
|
|
||||||
This General Public License does not permit incorporating your program into
|
|
||||||
proprietary programs. If your program is a subroutine library, you may
|
|
||||||
consider it more useful to permit linking proprietary applications with the
|
|
||||||
library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License.
|
|
||||||
@ -1,109 +0,0 @@
|
|||||||
# 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
|
|
||||||
@ -1,601 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Backend
|
|
||||||
*
|
|
||||||
* @copyright Olivier Meunier & Association Dotclear
|
|
||||||
* @copyright GPL-2.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
|
||||||
|
|
||||||
dcPage::check('usage,contentadmin');
|
|
||||||
$core->auth->user_prefs->addWorkspace('interface');
|
|
||||||
?>
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="ROBOTS" content="NOARCHIVE,NOINDEX,NOFOLLOW" />
|
|
||||||
<meta name="GOOGLEBOT" content="NOSNIPPET" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Bibliothèque de styles - Dotclear - 2.7</title>
|
|
||||||
<link rel="icon" type="image/png" href="images/favicon96-login.png" />
|
|
||||||
<?php
|
|
||||||
$js = [];
|
|
||||||
if ($core->auth->user_prefs->interface->darkmode) {
|
|
||||||
echo dcPage::cssLoad('style/default-dark.css');
|
|
||||||
} else {
|
|
||||||
echo dcPage::cssLoad('style/default.css');
|
|
||||||
}
|
|
||||||
if ($core->auth->user_prefs->interface->htmlfontsize) {
|
|
||||||
$js['htmlFontSize'] = $core->auth->user_prefs->interface->htmlfontsize;
|
|
||||||
}
|
|
||||||
// Set some JSON data
|
|
||||||
echo dcUtils::jsJson('dotclear_init', $js);
|
|
||||||
?>
|
|
||||||
<script src="js/jquery/jquery.js"></script>
|
|
||||||
<script src="js/jquery/jquery-ui.custom.js"></script>
|
|
||||||
<script src="js/jquery/jquery.ui.touch-punch.js"></script>
|
|
||||||
<script src="js/jquery/jquery.pageTabs.js"></script>
|
|
||||||
<script src="js/jquery/jquery.biscuit.js"></script>
|
|
||||||
<script src="js/prepend.js"></script>
|
|
||||||
<script src="js/common.js"></script>
|
|
||||||
<script src="js/prelude.js"></script>
|
|
||||||
<script src="js/_charte.js"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body id="dotclear-admin" class="no-js guideline<?php $core->auth->user_prefs->interface->dynfontsize ? ' responsive-font' : '';?>">
|
|
||||||
<ul id="prelude">
|
|
||||||
<li><a href="#content">Aller au contenu</a></li>
|
|
||||||
<li><a href="#main-menu">Aller au menu</a></li>
|
|
||||||
<li><a href="#qx">Aller à la recherche</a></li>
|
|
||||||
</ul>
|
|
||||||
<div id="header">
|
|
||||||
<h1><a href="./index.php"><span class="hidden">Dotclear</span></a></h1>
|
|
||||||
<div id="top-info-blog">
|
|
||||||
<p>Bibliothèque de styles - Dotclear - 2.6+</p>
|
|
||||||
</div>
|
|
||||||
<ul id="top-info-user"><li>Octobre 2013</li></ul>
|
|
||||||
</div><!-- /header -->
|
|
||||||
|
|
||||||
<div id="wrapper" class="clearfix">
|
|
||||||
<div class="hidden-if-no-js collapser-box"><button type="button" id="collapser" class="void-btn">
|
|
||||||
<img class="collapse-mm visually-hidden" src="images/collapser-hide.png" alt="Cacher le menu" />
|
|
||||||
<img class="expand-mm visually-hidden" src="images/collapser-show.png" alt="Montrer le menu" />
|
|
||||||
</button></div>
|
|
||||||
<div id="main">
|
|
||||||
<div id="content" class="clearfix">
|
|
||||||
<h2>Typographie</h2>
|
|
||||||
<h3 id="texte">Textes</h3>
|
|
||||||
<p>La font-size de base est à 1.2rem (la valeur <code>1rem</code> correspond à 10px). Si vous utilisez l'unité <code>rem</code> pensez à faire précéder la déclaration par son équivalent
|
|
||||||
en pixels pour rester compatible avec Internet Explorer. L'interlignage courant est à 1.5.</p>
|
|
||||||
<p>La liste suivante est de class <code>"nice"</code>. Elle est semblable aux listes ordinaires mais avec des puces carrées.</p>
|
|
||||||
<ul class="nice">
|
|
||||||
<li>Les textes courants sont en Arial, Helvetica ou sans-serif. </li>
|
|
||||||
<li>Le code adopte la fonte Andale Mono, Courier New ou monospace.</li>
|
|
||||||
<li>Les liens ont des aspects différents au focus et au survol. Il faut conserver cette distinction, nécessaire à l'accessibilité et l'ergonomie.</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h3 id="titres">Titre h3</h3>
|
|
||||||
<p>Le titre de niveau h1 est réservé au titre du site-admin. Le titre de niveau h2 est réservé au breadcrumb/titre de la page courante. On utilise les titres de niveau h3 en premier niveau de titre à l'intérieur des pages, comme sur la page Import/Export.</p>
|
|
||||||
<p>Il ne faut pas choisir un niveau de titre en fonction de son aspect mais respecter une hiérarchie cohérente. On peut obtenir visuellement l'aspect d'un titre h3 en donnant à l'élément la class <code>"as_h3"</code>.</p>
|
|
||||||
<h4>Titre de niveau h4</h4>
|
|
||||||
<p>On peut obtenir visuellement l'aspect d'un titre h4 en donnant à l'élément la class <code>"as_h4"</code>.</p>
|
|
||||||
<h5>Titre de niveau h5</h5>
|
|
||||||
<p>Le titre de niveau h5 est assez peu employé mais son style est prévu. Dans une admin de base, on utilise les niveaux
|
|
||||||
h5 pour certains éléments du sidebar du billet, mais un style particulier leur est alors appliqué pour ressembler aux autres
|
|
||||||
items de ce sidebar.</p>
|
|
||||||
<div class="fieldset">
|
|
||||||
<h4>Titres des encadrés</h4>
|
|
||||||
<p>Les titres de boîte encadrées (div de class <code>"fieldset"</code>, comme ici) se présentent comme ci-dessus.</p>
|
|
||||||
<p>On peut utiliser, quel que soit le niveau hx de cet intertitre la class <code>"pretty-title"</code> pour obtenir l'effet ci-dessus.</p>
|
|
||||||
</div>
|
|
||||||
<h4 class="smart-title">Autre variante</h4>
|
|
||||||
<p>On dispose également d'une class <code>"smart-title"</code> pour obtenir une présentation comme celle du titre de ce paragraphe.</p>
|
|
||||||
|
|
||||||
<h2>Layouts</h2>
|
|
||||||
|
|
||||||
<h3 id="onglets">Onglets</h3>
|
|
||||||
<p>Les descriptions des constructions en multi-colonnes ci-dessous présentent un exemple de répartition en onglets.</p>
|
|
||||||
<p>Chacun de ces onglets doit être défini à l'aide d'une <code><div class="multi-part"></code>. Ils seront alors automatiquement présentés sous forme d'onglets.</p>
|
|
||||||
|
|
||||||
<h3 id="multi-colonnage">Multi-colonnage</h3>
|
|
||||||
<div id="one-box" class="multi-part" title="One-box">
|
|
||||||
<h4>Boîtes distribuées horizontalement</h4>
|
|
||||||
<div class="one-box">
|
|
||||||
<div class="box">
|
|
||||||
<p><span class="step">1</span> Toutes les boîtes de class <code>"box"</code> placées à l'intérieur d'une boîte de class <code>"one-box"</code> se distribuent horizontalement (imaginez que chaque boîte est un mot dans un paragraphe). Si les largeurs de ces boîtes ne sont pas spécifiquement définies dans la CSS, elle s'ajustent à leur contenu.</p>
|
|
||||||
</div>
|
|
||||||
<div class="box">
|
|
||||||
<p><span class="step">2</span> Voici une petite boîte.</p>
|
|
||||||
</div>
|
|
||||||
<div class="box">
|
|
||||||
<p><span class="step">3</span> Une autre petite boîte.</p>
|
|
||||||
</div>
|
|
||||||
<div class="box">
|
|
||||||
<p><span class="step">4</span> Par défaut les « lignes » de boîtes <code>"box"</code> sont justifiées au sein de la boîte <code>"one-box"</code> et l'espacement se répartit entre elles.</p>
|
|
||||||
</div>
|
|
||||||
<div class="box">
|
|
||||||
<p><span class="step">5</span> Si vous souhaitez un autre alignement des boîtes entre elles vous pouvez ajouter les class :</p>
|
|
||||||
<ul class="nice clear">
|
|
||||||
<li><code>"txt-left"</code>,</li>
|
|
||||||
<li><code>"txt-right"</code></li>
|
|
||||||
<li>ou <code>"txt-center"</code></li>
|
|
||||||
</ul>
|
|
||||||
<p>à la class <code>"one-box"</code>.</p>
|
|
||||||
</div>
|
|
||||||
<div class="box">
|
|
||||||
<p><span class="step">6</span> Le cadre placé ici autour de chaque boîte ne fait pas partie des styles par défaut.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="two-boxes" class="multi-part" title="Two-boxes">
|
|
||||||
<h4>Boîtes distribuées deux par deux</h4>
|
|
||||||
<div>
|
|
||||||
<div class="two-boxes odd">
|
|
||||||
<p><span class="step">1</span> Les boîtes de class <code>"two-boxes"</code> ont une règle CSS <code>display:inline-block;</code>. Elles se rangent alternativement à gauche et à droite. Pour plus de clarté, les blocs sont ici numérotés avec leur ordre dans le flux.</p>
|
|
||||||
</div><!--
|
|
||||||
--><div class="two-boxes even">
|
|
||||||
<p><span class="step">2</span> On peut assortir une boîte des class <code>"odd"</code> (nothing left) et <code>"even"</code> pour que les marges se placent correctement.</p>
|
|
||||||
</div><!--
|
|
||||||
--><div class="two-boxes odd">
|
|
||||||
<p><span class="step">3</span> Attention, il faut soit ne pas retourner à la ligne entre la fermeture d'une boîte <code>"two-boxes"</code> et l'ouverture de la suivante soit adopter la méthode de commentaire vide mise en place ici et expliquée chez <a href="https://www.alsacreations.com/astuce/lire/1432-display-inline-block-espaces-indesirables.html">Alsacréations</a> (« Méthode 2 »).</p>
|
|
||||||
</div><!--
|
|
||||||
--><div class="two-boxes even">
|
|
||||||
<div class="two-boxes odd">
|
|
||||||
<p><span class="step">4</span> On peut bien sûr imbriquer des boîtes de class <code>"two-boxes"</code>
|
|
||||||
au sein d'une boîte <code>"two-boxes" afin qu'elles…</code>…</p>
|
|
||||||
</div><div class="two-boxes even">
|
|
||||||
<p><span class="step">4 bis</span>… se distribuent horizontalement comme dans une boîte <code>"one-box"</code>.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="three-boxes" class="multi-part" title="Three-boxes">
|
|
||||||
<h4>Boîtes distribuées trois par trois</h4>
|
|
||||||
<div>
|
|
||||||
<div class="three-boxes">
|
|
||||||
<div class="box">
|
|
||||||
<p>Sur le même principe que les « two-boxes » on peut utiliser des boîtes de class <code>"three-boxes"</code> pour répartir les contenus sur trois colonnes de 30% chacune (le reste est occupé par les marges).</p>
|
|
||||||
</div>
|
|
||||||
</div><!--
|
|
||||||
--><div class="three-boxes">
|
|
||||||
<div class="box">
|
|
||||||
<p>Comme pour les "two-boxes" il faut soit ne pas laisser d'espace ou de retour à la ligne entre les boîtes, soit adopter la méthode recommandée plus haut.</p>
|
|
||||||
</div>
|
|
||||||
</div><!--
|
|
||||||
--><div class="three-boxes">
|
|
||||||
<div class="box">
|
|
||||||
<p>Dans les « two-boxes » comme dans les « three-boxes », on peut placer à l'intérieur plusieurs autres div de class="box" qui s'afficheront les unes à côté des autres ou l'une en dessous de l'autre selon la place dont elles disposent.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="two-cols-50-50" class="multi-part" title="Two-cols (50/50)">
|
|
||||||
<h4>Deux colonnes flottantes de largeurs égales</h4>
|
|
||||||
<div class="two-cols clearfix">
|
|
||||||
<div class="col">
|
|
||||||
<p>La div englobante porte la class <code>"two-cols"</code>, chacune de ses div porte la class <code>"col"</code>.
|
|
||||||
Sans autre précision les deux colonnes sont d'égale largeur.</p>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<p>Attention : ces colonnes sont construites avec des flottants, il faut donc penser à mettre une class <code>clear</code> à l'élément suivant ou ajouter la class <code>"clearfix"</code> à la <code>div class="two-cols"</code>.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="two-cols-70-30" class="multi-part" title="Two-cols (70/30)">
|
|
||||||
<h4>Deux colonnes flottantes de largeurs inégales</h4>
|
|
||||||
<div class="two-cols clearfix">
|
|
||||||
<div class="col70">
|
|
||||||
<p><span class="step">col70</span> La div englobante porte la class <code>"two-cols"</code>.
|
|
||||||
Pour obtenir des colonnes inégales, on dispose des classes <code>"col70"</code> et <code>col30</code> à attribuer à l'une ou à l'autre de ses colonnes.</p>
|
|
||||||
</div>
|
|
||||||
<div class="col30">
|
|
||||||
<p><span class="step">col30</span> Penser à mettre une class <code>"clear"</code> à l'élément suivant ou ajouter la class <code>"clearfix"</code> <code>div class="two-cols"</code>.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="three-cols" class="multi-part" title="Three-cols (deprecated)">
|
|
||||||
<h4>Trois colonnes flottantes de largeurs égales</h4>
|
|
||||||
<p class="warning"><strong>Deprecated.</strong> Ces règles sont conservées dans la 2.6 par souci de rétro-compatibilité mais il est recommandé d'utiliser désormais le colonnage <a href="#three-boxes">three-boxes</a>.</p>
|
|
||||||
<div class="three-cols clearfix">
|
|
||||||
<div class="col">
|
|
||||||
<h5>Colonne 1</h5>
|
|
||||||
<p>La div englobante porte la class <code>"three-cols"</code>, chacune de ses div porte la class <code>"col"</code>. Les trois colonnes sont d'égale largeur.</p>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<h5>Colonne 2</h5>
|
|
||||||
<p>Voici une deuxième colonne. N'oubliez pas d'ajouter la class <code>"clearfix"</code> à la class <code>"three-cols"</code> ou un élément de class <code>"clear"</code> après cet élément.</p>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<h5>Colonne 3</h5>
|
|
||||||
<p>Voilà la troisième colonne.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
<p><strong>Note :</strong> dans les exemples les valeurs et les numérotations sont placées dans un <code>span class="step"</code> (et ressortent donc dans un petit bloc à fond gris).</p>
|
|
||||||
|
|
||||||
<h2>Interactions</h2>
|
|
||||||
|
|
||||||
<h3 id="elements">Éléments de formulaire</h3>
|
|
||||||
<form class="two-cols clearfix" action="#">
|
|
||||||
<div class="col">
|
|
||||||
<p><label for="ex1">Label simple + input text :</label><input id="ex1" type="text" /></p>
|
|
||||||
<p class="form-note">p class="form-note".</p>
|
|
||||||
<p><label for="ex4" class="classic">Label class="classic" + input text :</label> <input id="ex4" type="text" /></p>
|
|
||||||
<p><label for="ex2" class="required"><abbr title="Champ obligatoire">*</abbr> Label class="required" :</label> <input id="ex2" type="text" required placeholder="exemple" /><span class="form-note">span class="form-note"</span></p>
|
|
||||||
<p><label for="ex11" class="bold">Label class="bold" :</label> <input id="ex11" type="text" /></p>
|
|
||||||
<p class="form-note">La class="bold" est bien sûr à écrire en minuscules.</p>
|
|
||||||
<p><label for="ex3">Input class="maximal" :</label> <input id="ex3" type="text" class="maximal" /></p>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<p class="field"><label for="ex5">p.field label + input :</label><input id="ex5" type="text" /></p>
|
|
||||||
<p class="field"><label for="ex6">p.field label + select :</label>
|
|
||||||
<select id="ex6"><option value="opt2">Option 2</option><option selected="selected" value="opt2">Option 2</option></select>
|
|
||||||
</p>
|
|
||||||
<p><label class="classic" for="ex7"><input type="checkbox" checked="checked" id="ex7" value="1" name="ex7" />
|
|
||||||
Checkbox (label.classic)</label></p>
|
|
||||||
<p><label class="classic" for="ex8-1"><input type="radio" checked="checked" id="ex8-1" value="ex8-1" name="ex8-1" />
|
|
||||||
Bouton radio 1 (label.classic)</label></p>
|
|
||||||
<p><label class="classic" for="ex8-2"><input type="radio" id="ex8-2" value="ex8-2" name="ex8-2" />
|
|
||||||
Bouton radio 2 (label.classic)</label></p>
|
|
||||||
<p class="form-note">Les checkboxes et les boutons radio sont dans la balise <label>.</p>
|
|
||||||
<p><label class="classic" for="ex9"><input type="checkbox"
|
|
||||||
checked="checked" id="ex9" value="1" title="intitulé du champ" /></label> <label
|
|
||||||
for="ex10" class="classic">checkbox.classic + label class="classic" :</label> <input id="ex10" type="text" /></p>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<form action="#" class="clear">
|
|
||||||
<fieldset>
|
|
||||||
<legend>Légende de fieldset</legend>
|
|
||||||
<p>Attention: Les fieldsets ne doivent être utilisés que pour isoler un groupe de champs au sein d'un formulaire.</p>
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<h3 id="boutons">Boutons</h3>
|
|
||||||
<div class="clearfix">
|
|
||||||
<p><a class="button add">a.button.add</a> Se place en haut à droite (dans un p.top-add)</p>
|
|
||||||
<p><input type="button" value="Type button" /> <a href="#" class="button">a.button</a> <input type="reset" value="Type reset" /> <a href="#" class="button reset">a.reset</a></p>
|
|
||||||
<p><input type="submit" value="Type submit" /> <input type="submit" class="delete" value="Type submit class delete" /> <a href="#" class="button delete">a.button delete</a></p>
|
|
||||||
<p><input type="submit" value="Type submit class disabled" class="disabled" /></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3 id="messages">Messages</h3>
|
|
||||||
<h4 class="smart-title">Messages système</h4>
|
|
||||||
<p>Il existe quatre types de messages système auxquels correspondent des classes CSS : .error, .message, .success, .warning-msg. Ils s'affichent en haut de page, sous le titre/breadcrumb.</p>
|
|
||||||
<div class="message">
|
|
||||||
<p>Message simple. Le plus souvent horodaté dcPage::message</p>
|
|
||||||
</div>
|
|
||||||
<div class="success">
|
|
||||||
<p>Message de succès. Le plus souvent horodaté dcPage::success</p>
|
|
||||||
</div>
|
|
||||||
<div class="warning-msg">
|
|
||||||
<p>Message warning. Non horodaté dcPage::warning</p>
|
|
||||||
</div>
|
|
||||||
<div class="error">
|
|
||||||
<p>Message d'erreur. Non horodaté dcPage::error</p>
|
|
||||||
</div>
|
|
||||||
<p>La classe .static-msg peut être utilisée directement pour affichage en haut de page :</p>
|
|
||||||
<div class="static-msg">
|
|
||||||
<p>Comme le message simple mais sans effets de transition.</p>
|
|
||||||
</div>
|
|
||||||
<p>Un type de message réservé à Dotclear peut s'afficher en haut de la page :</p>
|
|
||||||
<div class="dc-update">
|
|
||||||
<h3>Dotclear 42 est disponible</h3>
|
|
||||||
<p><a class="button submit" href="#">Mettre à jour maintenant</a>
|
|
||||||
<a class="button" href="u#">Me le rappeler plus tard</a></p>
|
|
||||||
<p class="updt-info"><a href="#">Informations sur cette version</a></p>
|
|
||||||
</div>
|
|
||||||
<h4 class="smart-title">Messages contextuels</h4>
|
|
||||||
<p class="warn">Paragraphe de message d'alerte class warn ou warning.</p>
|
|
||||||
<p class="info">Paragraphe de message de class info.</p>
|
|
||||||
<p>Ces messages sont en display:inline-block. Le fond s'adapte à la longueur du message.</p>
|
|
||||||
|
|
||||||
<h2>Navigation</h2>
|
|
||||||
|
|
||||||
<h3 id="direct">Selecteur d'accès direct</h3>
|
|
||||||
<p>Sur des pages longues et denses comme les pages about:config ou about:preferences, on peut utiliser un sélecteur pour faciliter l'accès direct aux sections.</p>
|
|
||||||
<p class="anchor-nav">
|
|
||||||
<label class="classic" for="lp_nav">Aller à : </label>
|
|
||||||
<select id="lp_nav" name="lp_nav">
|
|
||||||
<option value="#l_accessibility">accessibility</option>
|
|
||||||
<option value="#l_dashboard">dashboard</option>
|
|
||||||
<option value="#l_dmhostingmonitor">dmhostingmonitor</option>
|
|
||||||
<option value="#l_dmpending">dmpending</option>
|
|
||||||
<option value="#l_favorites">favorites</option>
|
|
||||||
<option value="#l_filters">filters</option>
|
|
||||||
<option value="#l_interface">interface</option>
|
|
||||||
<option value="#l_lists">lists</option>
|
|
||||||
<option value="#l_toggles">toggles</option>
|
|
||||||
</select>
|
|
||||||
<input type="submit" id="lp_submit" value="Ok" style="display: none;" />
|
|
||||||
<input type="hidden" value="aboutConfig" name="p" />
|
|
||||||
</p>
|
|
||||||
<h3 id="prevnext">Navigation contextuelle</h3>
|
|
||||||
<p><a title="Titre du lien" href="https://fr.dotclear.org/blog" class="onblog_link outgoing">Lien vers le blog <img alt="" src="images/outgoing-link.svg" /></a></p>
|
|
||||||
<p class="nav_prevnext"><a title="Titre de l'élément précédente" href="post.php?id=4145">« Élément précédent</a> | <a title="Titre de l'élément suivant" href="#">Élément suivant »</a></p>
|
|
||||||
|
|
||||||
<h3 id="pseudo-tabs">Pseudo-onglets </h3>
|
|
||||||
<p>Les pseudo-onglets permettent d'ajouter des sous-pages qui sont des liens vers d'autres pages, par opposition aux onglets qui sont des sections internes à la page.</p>
|
|
||||||
<p>Les pseudo-onglets sont à positionner immédiatement après le breadcrumb (ici un hr simule le trait sous le breadcrumb).</p>
|
|
||||||
<p>Ces pseudo-onglets doivent être définis avec un <code><ul class="pseudo-tabs"></code> et des <code><li></code>.</p>
|
|
||||||
<hr style="margin-bottom: .75em;" />
|
|
||||||
<ul class="pseudo-tabs">
|
|
||||||
<li><a href="#">Page 1</a></li>
|
|
||||||
<li><a href="#">Autre faux onglet</a></li>
|
|
||||||
<li><a href="#" class="active">Onglet actif</a></li>
|
|
||||||
<li><a href="#">Liste 4</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2 id="common">Tableaux</h2>
|
|
||||||
<p>Il existe deux mises en forme type de tableaux selon que l'on cherche à faire un tableau ordinaire
|
|
||||||
ou un tableau dont on peut déplacer les lignes par glisser déposer (voir plus bas). Cependant certaines règles
|
|
||||||
sont communes à tout les tableaux.</p>
|
|
||||||
|
|
||||||
<h3>Règles communes</h3>
|
|
||||||
<h4>Largeur du tableau</h4>
|
|
||||||
<p>Sauf pour des tableaux particuliers (absents dans l'admin mais qui pourraient être nécessaires
|
|
||||||
à un plugin,les tableaux occupent toute la largeur de la page. Afin que les tableaux soient consultables
|
|
||||||
sur un mobile en navigant horizontalement, on englobe le tableau dans une <code>div class="table-outer"</code>,
|
|
||||||
qui servira de « conteneur ».</p>
|
|
||||||
<h4>Accessibilité</h4>
|
|
||||||
<p>Les éléments caption, th, scope sont nécessaires à l'accessibilité. Ne les oubliez pas ! ».
|
|
||||||
On peut utiliser la <code>class="hidden"</code> sur l'élément <code>caption</code> (qui accueille
|
|
||||||
le titre du tableau) si vous ne souhaitez pas qu'il soit affiché sur la page.</p>
|
|
||||||
<h4>Les classes</h4>
|
|
||||||
<p>Des classes particulières peuvent être attribuées aux lignes :</p>
|
|
||||||
<ul>
|
|
||||||
<li><code>line</code> (systématique) : pour les traits horizontaux et le fond gris léger
|
|
||||||
au survol ;</li>
|
|
||||||
<li><code>offline</code> : pour un noir estompé (gris quoi).</li>
|
|
||||||
</ul>
|
|
||||||
<p>Des classes particulières peuvent être appliquées aux cellules :</p>
|
|
||||||
<ul>
|
|
||||||
<li><code>nowrap</code> : pas de retour à la ligne dans la cellule, quelle que soit la
|
|
||||||
largeur de la page ;</li>
|
|
||||||
<li><code>maximal</code> : la cellule prendra toute la largeur restante disponible ;</li>
|
|
||||||
<li><code>count</code> : le contenu de la cellule sera aligné à droite avec un petit retrait.</li>
|
|
||||||
</ul>
|
|
||||||
<h3 id="courants">Tableau classique</h3>
|
|
||||||
<div class="table-outer">
|
|
||||||
<table>
|
|
||||||
<caption class="hidden">Liste des publications</caption>
|
|
||||||
<tr>
|
|
||||||
<th colspan="2" class="first">Titre</th>
|
|
||||||
<th scope="col">Date</th>
|
|
||||||
<th scope="col">Catégorie</th>
|
|
||||||
<th scope="col">Auteur</th>
|
|
||||||
<th scope="col">Commentaires</th>
|
|
||||||
<th scope="col">Rétroliens</th>
|
|
||||||
<th scope="col">État</th>
|
|
||||||
</tr>
|
|
||||||
<tr class="line">
|
|
||||||
<td class="nowrap"><input type="checkbox" name="name1" value="value1" /></td>
|
|
||||||
<td class="maximal" scope="row"><a href="#">Mon cher Franck</a></td>
|
|
||||||
<td class="nowrap count">06/08/2013 19:16</td>
|
|
||||||
<td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>
|
|
||||||
<td class="nowrap">kozlika</td><td class="nowrap count">4</td>
|
|
||||||
<td class="nowrap count">0</td><td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> <img alt="Sélectionné" title="Sélectionné" src="images/selected.png" /> </td>
|
|
||||||
</tr>
|
|
||||||
<tr class="line offline">
|
|
||||||
<td class="nowrap"><input type="checkbox" name="name2" value="value2" /></td>
|
|
||||||
<td class="maximal" scope="row"><a href="#">Dotclear 2.3.0</a></td>
|
|
||||||
<td class="nowrap count">16/05/2011 22:29</td>
|
|
||||||
<td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>
|
|
||||||
<td class="nowrap">kozlika</td><td class="nowrap count">5</td>
|
|
||||||
<td class="nowrap count">0</td><td class="nowrap status"><img alt="Non publié" title="Non publié" src="images/check-off.png" /> <img alt="Sélectionné" title="Sélectionné" src="images/selected.png" /> </td>
|
|
||||||
</tr>
|
|
||||||
<tr class="line">
|
|
||||||
<td class="nowrap"><input type="checkbox" name="entries[]" value="2148" /></td>
|
|
||||||
<td class="maximal" scope="row"><a href="#">Causons opéra au Tamm Bara</a></td>
|
|
||||||
<td class="nowrap count">24/11/2009 23:10</td>
|
|
||||||
<td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>
|
|
||||||
<td class="nowrap">kozlika</td>
|
|
||||||
<td class="nowrap count">4</td><td class="nowrap count">1</td>
|
|
||||||
<td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> </td>
|
|
||||||
</tr>
|
|
||||||
<tr class="line">
|
|
||||||
<td class="nowrap"><input type="checkbox" name="entries[]" value="2136" /></td>
|
|
||||||
<td class="maximal" scope="row"><a href="#">Souffler six bougies</a></td>
|
|
||||||
<td class="nowrap count">14/08/2009 00:00</td><td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>
|
|
||||||
<td class="nowrap">kozlika</td>
|
|
||||||
<td class="nowrap count">4</td><td class="nowrap count">2</td><td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> </td>
|
|
||||||
</tr>
|
|
||||||
<tr class="line">
|
|
||||||
<td class="nowrap"><input type="checkbox" name="entries[]" value="2129" /></td>
|
|
||||||
<td class="maximal" scope="row"><a href="#">Dotclear et grenadine, troisième édition</a></td>
|
|
||||||
<td class="nowrap count">15/06/2009 07:39</td>
|
|
||||||
<td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>
|
|
||||||
<td class="nowrap">kozlika</td>
|
|
||||||
<td class="nowrap count">9</td>
|
|
||||||
<td class="nowrap count">1</td>
|
|
||||||
<td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> </td>
|
|
||||||
</tr>
|
|
||||||
<tr class="line">
|
|
||||||
<td class="nowrap"><input type="checkbox" name="entries[]" value="2111" /></td>
|
|
||||||
<td class="maximal" scope="row"><a href="#">L'abc dotclear est né</a></td>
|
|
||||||
<td class="nowrap count">19/03/2009 10:31</td><td class="nowrap"><a href="#">Les aventures du clafoutis</a></td>
|
|
||||||
<td class="nowrap">kozlika</td>
|
|
||||||
<td class="nowrap count">1</td><td class="nowrap count">0</td>
|
|
||||||
<td class="nowrap status"><img alt="Publié" title="Publié" src="images/check-on.png" /> </td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3 id="dragable">Tableau avec ordonnancement</h3>
|
|
||||||
<p>Les tableaux permettant l'ordonnancement doivent offrir la possibilité d'effectuer le classement grâce à
|
|
||||||
des inputs placés en début de ligne pour que le classement soit possible même lorsque cette fonctionnalité est
|
|
||||||
désactivée (via les préférences utilisateurs, voire une désactivation complète du javascript dans le navigateur).</p>
|
|
||||||
<div class="table-outer">
|
|
||||||
<table class="maximal dragable">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th colspan="3">Titre</th>
|
|
||||||
<th>Date</th>
|
|
||||||
<th>Auteur</th>
|
|
||||||
<th>Commentaires</th>
|
|
||||||
<th>Rétroliens</th>
|
|
||||||
<th>État</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="pageslist">
|
|
||||||
<tr class="line" id="p10899">
|
|
||||||
<td class="nowrap handle minimal">
|
|
||||||
<input type="text" size="2" name="order[10899]" maxlength="3" value="1" class="position" title="position de Mentions légales" />
|
|
||||||
</td>
|
|
||||||
<td class="nowrap">
|
|
||||||
<input type="checkbox" name="entries[]" value="10899" title="Sélectionner cette page" />
|
|
||||||
</td>
|
|
||||||
<td class="maximal"><a href="#">Mentions légales</a>
|
|
||||||
</td>
|
|
||||||
<td class="nowrap">17/12/2008 07:35</td>
|
|
||||||
<td class="nowrap">franck</td>
|
|
||||||
<td class="nowrap">0</td>
|
|
||||||
<td class="nowrap">0</td>
|
|
||||||
<td class="nowrap status">
|
|
||||||
<img alt="Publié" title="Publié" src="images/check-on.png" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="line" id="p10937">
|
|
||||||
<td class="nowrap handle minimal">
|
|
||||||
<input type="text" size="2" name="order[10937]" maxlength="3" value="2" class="position" title="position de Page active et cachée" />
|
|
||||||
</td>
|
|
||||||
<td class="nowrap">
|
|
||||||
<input type="checkbox" name="entries[]" value="10937" title="Sélectionner cette page" />
|
|
||||||
</td>
|
|
||||||
<td class="maximal"><a href="#">Page active et cachée</a>
|
|
||||||
</td>
|
|
||||||
<td class="nowrap">26/10/2012 11:08</td>
|
|
||||||
<td class="nowrap">admin</td>
|
|
||||||
<td class="nowrap">0</td>
|
|
||||||
<td class="nowrap">0</td>
|
|
||||||
<td class="nowrap status">
|
|
||||||
<img alt="Publié" title="Publié" src="images/check-on.png" />
|
|
||||||
<img alt="Masqué" title="Masqué" src="images/hidden.png" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="line offline" id="p11047">
|
|
||||||
<td class="nowrap handle minimal">
|
|
||||||
<input type="text" size="2" name="order[11047]" maxlength="3" value="3" class="position" title="position de Page révisionnable" />
|
|
||||||
</td>
|
|
||||||
<td class="nowrap">
|
|
||||||
<input type="checkbox" name="entries[]" value="11047" title="Sélectionner cette page" />
|
|
||||||
</td>
|
|
||||||
<td class="maximal"><a href="#">Page révisionnable</a>
|
|
||||||
</td>
|
|
||||||
<td class="nowrap">14/12/2012 13:26</td>
|
|
||||||
<td class="nowrap">admin</td>
|
|
||||||
<td class="nowrap">0</td>
|
|
||||||
<td class="nowrap">0</td>
|
|
||||||
<td class="nowrap status">
|
|
||||||
<img alt="En attente" title="En attente" src="images/check-wrn.png" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="line offline" id="p10939">
|
|
||||||
<td class="nowrap handle minimal">
|
|
||||||
<input type="text" size="2" name="order[10939]" maxlength="3" value="4" class="position" title="position de Programme" />
|
|
||||||
</td>
|
|
||||||
<td class="nowrap">
|
|
||||||
<input type="checkbox" name="entries[]" value="10939" title="Sélectionner cette page" />
|
|
||||||
</td>
|
|
||||||
<td class="maximal"><a href="#">Programme</a>
|
|
||||||
</td>
|
|
||||||
<td class="nowrap">26/10/2020 11:23</td>
|
|
||||||
<td class="nowrap">admin</td>
|
|
||||||
<td class="nowrap">0</td>
|
|
||||||
<td class="nowrap">0</td>
|
|
||||||
<td class="nowrap status">
|
|
||||||
<img alt="Programmé" title="Programmé" src="images/scheduled.png" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="line offline" id="p10940">
|
|
||||||
<td class="nowrap handle minimal">
|
|
||||||
<input type="text" size="2" name="order[10940]" maxlength="3" value="5" class="position" title="position de Protégée" />
|
|
||||||
</td>
|
|
||||||
<td class="nowrap">
|
|
||||||
<input type="checkbox" name="entries[]" value="10940" title="Sélectionner cette page" />
|
|
||||||
</td>
|
|
||||||
<td class="maximal"><a href="#">Protégée</a>
|
|
||||||
</td>
|
|
||||||
<td class="nowrap">26/10/2012 11:23</td>
|
|
||||||
<td class="nowrap">admin</td>
|
|
||||||
<td class="nowrap">0</td>
|
|
||||||
<td class="nowrap">0</td>
|
|
||||||
<td class="nowrap status">
|
|
||||||
<img alt="En attente" title="En attente" src="images/check-wrn.png" />
|
|
||||||
<img alt="Protégé" title="Protégé" src="images/locker.png" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2 id="iconset">Icônes</h2>
|
|
||||||
<p>Les icônes utilisées dans l'administration sont présentes en deux formats 64*64px pour les grandes
|
|
||||||
(qui sont affichées sur le tableau de bord si la page correspondante est choisie en favori par l'utilisateur) et
|
|
||||||
16*16px pour les petits formats.</p>
|
|
||||||
<p>La plupart sont dérivées de la fonte d'icônes <a href="https://www.elegantthemes.com/blog/resources/elegant-icon-font">Elegant Font</a>. Les autres sont des images vectorielles réalisées
|
|
||||||
par la DC Team. Nous les avons nommées <em>Traviata</em>. La palette de couleurs utilisée est la suivante :</p>
|
|
||||||
<p class="txt-center"><img src="images/palette-traviata.png" alt="palette des couleurs utilisées pour les icônes" /></p>
|
|
||||||
<p class="txt-center">Bleu : #137bbb - Vert : #9ac123 - Rouge : #c44d58 - Bleu ciel : #a2cbe9 - Gris clair : #ececec -
|
|
||||||
Gris moyen : #b2b2b2 - Gris foncé : #676e78.</p>
|
|
||||||
</div><!-- /content -->
|
|
||||||
</div><!-- /main -->
|
|
||||||
<div id="main-menu">
|
|
||||||
<ul><li class="pretty-title">Typographie
|
|
||||||
<ul>
|
|
||||||
<li><a href="#texte">Texte</a></li>
|
|
||||||
<li><a href="#titres">Titres hx</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="pretty-title">Layouts
|
|
||||||
<ul>
|
|
||||||
<li><a href="#onglets">Onglets</a></li>
|
|
||||||
<li><a href="#multi-colonnage">Multi-colonnage</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="pretty-title">Interactions
|
|
||||||
<ul>
|
|
||||||
<li><a href="#elements">Éléments de formulaire</a></li>
|
|
||||||
<li><a href="#boutons">Boutons</a></li>
|
|
||||||
<li><a href="#messages">Messages</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="pretty-title">Navigation
|
|
||||||
<ul>
|
|
||||||
<li><a href="#direct">Accès direct</a></li>
|
|
||||||
<li><a href="#prevnext">Précédent, suivant</a></li>
|
|
||||||
<li><a href="#pseudo-tabs">Pseudo-onglets</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="pretty-title">Tableaux
|
|
||||||
<ul>
|
|
||||||
<li><a href="#commons">Règles communes</a></li>
|
|
||||||
<li><a href="#courants">Tableaux courants</a></li>
|
|
||||||
<li><a href="#dragables">Tableaux ordonnancés</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="info vertical-separator">
|
|
||||||
<p>Cette page vise à présenter les règles graphiques et conventions utilisées dans les pages de l'administration
|
|
||||||
d'une installation Dotclear, à l'usage des contributeurs et développeurs d'extensions. Elle en est elle-même
|
|
||||||
une illustration. L'observation de son code source peut donc servir de complément aux descriptions.</p>
|
|
||||||
</div>
|
|
||||||
</div><!-- /main-menu -->
|
|
||||||
|
|
||||||
<div id="footer">
|
|
||||||
<a href="https://dotclear.org/" title="Merci de manger des clafoutis."><img src="style/dc_logos/w-dotclear90.png" alt="Merci d'utiliser Dotclear 2.6-dev." /></a>
|
|
||||||
</div><!-- /footer -->
|
|
||||||
<!--
|
|
||||||
.
|
|
||||||
,;:'`'::
|
|
||||||
__||
|
|
||||||
_____/LLLL\_
|
|
||||||
\__________"|
|
|
||||||
~^~^~^~^~^~^~^~^~^~
|
|
||||||
-->
|
|
||||||
</div><!-- /wrapper -->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,410 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Backend
|
|
||||||
*
|
|
||||||
* @copyright Olivier Meunier & Association Dotclear
|
|
||||||
* @copyright GPL-2.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
|
||||||
|
|
||||||
# If we have a session cookie, go to index.php
|
|
||||||
if (isset($_SESSION['sess_user_id'])) {
|
|
||||||
$core->adminurl->redirect('admin.home');
|
|
||||||
}
|
|
||||||
|
|
||||||
# Loading locales for detected language
|
|
||||||
# That's a tricky hack but it works ;)
|
|
||||||
$dlang = http::getAcceptLanguage();
|
|
||||||
$dlang = ($dlang == '' ? 'en' : $dlang);
|
|
||||||
if ($dlang != 'en' && preg_match('/^[a-z]{2}(-[a-z]{2})?$/', $dlang)) {
|
|
||||||
l10n::lang($dlang);
|
|
||||||
l10n::set(dirname(__FILE__) . '/../locales/' . $dlang . '/main');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (defined('DC_ADMIN_URL')) {
|
|
||||||
$page_url = DC_ADMIN_URL . $core->adminurl->get('admin.auth');
|
|
||||||
} else {
|
|
||||||
$page_url = http::getHost() . $_SERVER['REQUEST_URI'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$change_pwd = $core->auth->allowPassChange() && isset($_POST['new_pwd']) && isset($_POST['new_pwd_c']) && isset($_POST['login_data']);
|
|
||||||
$login_data = !empty($_POST['login_data']) ? html::escapeHTML($_POST['login_data']) : null;
|
|
||||||
$recover = $core->auth->allowPassChange() && !empty($_REQUEST['recover']);
|
|
||||||
$safe_mode = !empty($_REQUEST['safe_mode']);
|
|
||||||
$akey = $core->auth->allowPassChange() && !empty($_GET['akey']) ? $_GET['akey'] : null;
|
|
||||||
$user_id = $user_pwd = $user_key = $user_email = null;
|
|
||||||
$err = $msg = null;
|
|
||||||
|
|
||||||
# Auto upgrade
|
|
||||||
if (empty($_GET) && empty($_POST)) {
|
|
||||||
require dirname(__FILE__) . '/../inc/dbschema/upgrade.php';
|
|
||||||
try {
|
|
||||||
if (($changes = dcUpgrade::dotclearUpgrade($core)) !== false) {
|
|
||||||
$msg = __('Dotclear has been upgraded.') . '<!-- ' . $changes . ' -->';
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$err = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# If we have POST login informations, go throug auth process
|
|
||||||
if (!empty($_POST['user_id']) && !empty($_POST['user_pwd'])) {
|
|
||||||
$user_id = !empty($_POST['user_id']) ? $_POST['user_id'] : null;
|
|
||||||
$user_pwd = !empty($_POST['user_pwd']) ? $_POST['user_pwd'] : null;
|
|
||||||
}
|
|
||||||
# If we have COOKIE login informations, go throug auth process
|
|
||||||
elseif (isset($_COOKIE['dc_admin']) && strlen($_COOKIE['dc_admin']) == 104) {
|
|
||||||
# If we have a remember cookie, go through auth process with user_key
|
|
||||||
$user_id = substr($_COOKIE['dc_admin'], 40);
|
|
||||||
$user_id = @unpack('a32', @pack('H*', $user_id));
|
|
||||||
if (is_array($user_id)) {
|
|
||||||
$user_id = trim($user_id[1]);
|
|
||||||
$user_key = substr($_COOKIE['dc_admin'], 0, 40);
|
|
||||||
$user_pwd = null;
|
|
||||||
} else {
|
|
||||||
$user_id = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Recover password
|
|
||||||
if ($recover && !empty($_POST['user_id']) && !empty($_POST['user_email'])) {
|
|
||||||
$user_id = !empty($_POST['user_id']) ? $_POST['user_id'] : null;
|
|
||||||
$user_email = !empty($_POST['user_email']) ? html::escapeHTML($_POST['user_email']) : '';
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$recover_key = $core->auth->setRecoverKey($user_id, $user_email);
|
|
||||||
|
|
||||||
$subject = mail::B64Header('Dotclear ' . __('Password reset'));
|
|
||||||
$message =
|
|
||||||
__('Someone has requested to reset the password for the following site and username.') . "\n\n" .
|
|
||||||
$page_url . "\n" . __('Username:') . ' ' . $user_id . "\n\n" .
|
|
||||||
__('To reset your password visit the following address, otherwise just ignore this email and nothing will happen.') . "\n" .
|
|
||||||
$page_url . '?akey=' . $recover_key;
|
|
||||||
|
|
||||||
$headers[] = 'From: ' . (defined('DC_ADMIN_MAILFROM') && DC_ADMIN_MAILFROM ? DC_ADMIN_MAILFROM : 'dotclear@local');
|
|
||||||
$headers[] = 'Content-Type: text/plain; charset=UTF-8;';
|
|
||||||
|
|
||||||
mail::sendMail($user_email, $subject, $message, $headers);
|
|
||||||
$msg = sprintf(__('The e-mail was sent successfully to %s.'), $user_email);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$err = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# Send new password
|
|
||||||
elseif ($akey) {
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$recover_res = $core->auth->recoverUserPassword($akey);
|
|
||||||
|
|
||||||
$subject = mb_encode_mimeheader('Dotclear ' . __('Your new password'), 'UTF-8', 'B');
|
|
||||||
$message =
|
|
||||||
__('Username:') . ' ' . $recover_res['user_id'] . "\n" .
|
|
||||||
__('Password:') . ' ' . $recover_res['new_pass'] . "\n\n" .
|
|
||||||
preg_replace('/\?(.*)$/', '', $page_url);
|
|
||||||
|
|
||||||
$headers[] = 'From: ' . (defined('DC_ADMIN_MAILFROM') && DC_ADMIN_MAILFROM ? DC_ADMIN_MAILFROM : 'dotclear@local');
|
|
||||||
$headers[] = 'Content-Type: text/plain; charset=UTF-8;';
|
|
||||||
|
|
||||||
mail::sendMail($recover_res['user_email'], $subject, $message, $headers);
|
|
||||||
$msg = __('Your new password is in your mailbox.');
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$err = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# Change password and retry to log
|
|
||||||
elseif ($change_pwd) {
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$tmp_data = explode('/', $_POST['login_data']);
|
|
||||||
if (count($tmp_data) != 3) {
|
|
||||||
throw new Exception();
|
|
||||||
}
|
|
||||||
$data = [
|
|
||||||
'user_id' => base64_decode($tmp_data[0]),
|
|
||||||
'cookie_admin' => $tmp_data[1],
|
|
||||||
'user_remember' => $tmp_data[2] == '1'
|
|
||||||
];
|
|
||||||
if ($data['user_id'] === false) {
|
|
||||||
throw new Exception();
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check login informations
|
|
||||||
$check_user = false;
|
|
||||||
if (isset($data['cookie_admin']) && strlen($data['cookie_admin']) == 104) {
|
|
||||||
$user_id = substr($data['cookie_admin'], 40);
|
|
||||||
$user_id = @unpack('a32', @pack('H*', $user_id));
|
|
||||||
if (is_array($user_id)) {
|
|
||||||
$user_id = trim($data['user_id']);
|
|
||||||
$user_key = substr($data['cookie_admin'], 0, 40);
|
|
||||||
$check_user = $core->auth->checkUser($user_id, null, $user_key) === true;
|
|
||||||
} else {
|
|
||||||
$user_id = trim($user_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$core->auth->allowPassChange() || !$check_user) {
|
|
||||||
$change_pwd = false;
|
|
||||||
throw new Exception();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($_POST['new_pwd'] != $_POST['new_pwd_c']) {
|
|
||||||
throw new Exception(__("Passwords don't match"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($core->auth->checkUser($user_id, $_POST['new_pwd']) === true) {
|
|
||||||
throw new Exception(__("You didn't change your password."));
|
|
||||||
}
|
|
||||||
|
|
||||||
$cur = $core->con->openCursor($core->prefix . 'user');
|
|
||||||
$cur->user_change_pwd = 0;
|
|
||||||
$cur->user_pwd = $_POST['new_pwd'];
|
|
||||||
$core->updUser($core->auth->userID(), $cur);
|
|
||||||
|
|
||||||
$core->session->start();
|
|
||||||
$_SESSION['sess_user_id'] = $user_id;
|
|
||||||
$_SESSION['sess_browser_uid'] = http::browserUID(DC_MASTER_KEY);
|
|
||||||
|
|
||||||
if ($data['user_remember']) {
|
|
||||||
setcookie('dc_admin', $data['cookie_admin'], strtotime('+15 days'), '', '', DC_ADMIN_SSL);
|
|
||||||
}
|
|
||||||
|
|
||||||
$core->adminurl->redirect('admin.home');
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$err = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# Try to log
|
|
||||||
elseif ($user_id !== null && ($user_pwd !== null || $user_key !== null)) {
|
|
||||||
# We check the user
|
|
||||||
$check_user = $core->auth->checkUser($user_id, $user_pwd, $user_key, false) === true;
|
|
||||||
if ($check_user) {
|
|
||||||
$check_perms = $core->auth->findUserBlog() !== false;
|
|
||||||
} else {
|
|
||||||
$check_perms = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$cookie_admin = http::browserUID(DC_MASTER_KEY . $user_id .
|
|
||||||
$core->auth->cryptLegacy($user_id)) . bin2hex(pack('a32', $user_id));
|
|
||||||
|
|
||||||
if ($check_perms && $core->auth->mustChangePassword()) {
|
|
||||||
$login_data = join('/', [
|
|
||||||
base64_encode($user_id),
|
|
||||||
$cookie_admin,
|
|
||||||
empty($_POST['user_remember']) ? '0' : '1'
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (!$core->auth->allowPassChange()) {
|
|
||||||
$err = __('You have to change your password before you can login.');
|
|
||||||
} else {
|
|
||||||
$err = __('In order to login, you have to change your password now.');
|
|
||||||
$change_pwd = true;
|
|
||||||
}
|
|
||||||
} elseif ($check_perms && !empty($_POST['safe_mode']) && !$core->auth->isSuperAdmin()) {
|
|
||||||
$err = __('Safe Mode can only be used for super administrators.');
|
|
||||||
} elseif ($check_perms) {
|
|
||||||
$core->session->start();
|
|
||||||
$_SESSION['sess_user_id'] = $user_id;
|
|
||||||
$_SESSION['sess_browser_uid'] = http::browserUID(DC_MASTER_KEY);
|
|
||||||
|
|
||||||
if (!empty($_POST['blog'])) {
|
|
||||||
$_SESSION['sess_blog_id'] = $_POST['blog'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($_POST['safe_mode']) && $core->auth->isSuperAdmin()) {
|
|
||||||
$_SESSION['sess_safe_mode'] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($_POST['user_remember'])) {
|
|
||||||
setcookie('dc_admin', $cookie_admin, strtotime('+15 days'), '', '', DC_ADMIN_SSL);
|
|
||||||
}
|
|
||||||
|
|
||||||
$core->adminurl->redirect('admin.home');
|
|
||||||
} else {
|
|
||||||
if (isset($_COOKIE['dc_admin'])) {
|
|
||||||
unset($_COOKIE['dc_admin']);
|
|
||||||
setcookie('dc_admin', false, -600, '', '', DC_ADMIN_SSL);
|
|
||||||
}
|
|
||||||
if ($check_user) {
|
|
||||||
$err = __('Insufficient permissions');
|
|
||||||
} else {
|
|
||||||
$err = __('Wrong username or password');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_GET['user'])) {
|
|
||||||
$user_id = $_GET['user'];
|
|
||||||
}
|
|
||||||
|
|
||||||
header('Content-Type: text/html; charset=UTF-8');
|
|
||||||
|
|
||||||
// Prevents Clickjacking as far as possible
|
|
||||||
header('X-Frame-Options: SAMEORIGIN'); // FF 3.6.9+ Chrome 4.1+ IE 8+ Safari 4+ Opera 10.5+
|
|
||||||
|
|
||||||
?>
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="<?php echo $dlang; ?>">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
|
||||||
<meta http-equiv="Content-Style-Type" content="text/css" />
|
|
||||||
<meta http-equiv="Content-Language" content="<?php echo $dlang; ?>" />
|
|
||||||
<meta name="ROBOTS" content="NOARCHIVE,NOINDEX,NOFOLLOW" />
|
|
||||||
<meta name="GOOGLEBOT" content="NOSNIPPET" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title><?php echo html::escapeHTML(DC_VENDOR_NAME); ?></title>
|
|
||||||
<link rel="icon" type="image/png" href="images/favicon96-logout.png" />
|
|
||||||
<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon" />
|
|
||||||
|
|
||||||
|
|
||||||
<?php
|
|
||||||
echo dcPage::jsCommon();
|
|
||||||
?>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="style/default.css" type="text/css" media="screen" />
|
|
||||||
|
|
||||||
<?php
|
|
||||||
# --BEHAVIOR-- loginPageHTMLHead
|
|
||||||
$core->callBehavior('loginPageHTMLHead');
|
|
||||||
|
|
||||||
echo dcPage::jsLoad('js/_auth.js');
|
|
||||||
?>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body id="dotclear-admin" class="auth">
|
|
||||||
|
|
||||||
<form action="<?php echo $core->adminurl->get('admin.auth'); ?>" method="post" id="login-screen">
|
|
||||||
<h1 role="banner"><?php echo html::escapeHTML(DC_VENDOR_NAME); ?></h1>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
if ($err) {
|
|
||||||
echo '<div class="error" role="alert">' . $err . '</div>';
|
|
||||||
}
|
|
||||||
if ($msg) {
|
|
||||||
echo '<p class="success" role="alert">' . $msg . '</p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($akey) {
|
|
||||||
echo '<p><a href="' . $core->adminurl->get('admin.auth') . '">' . __('Back to login screen') . '</a></p>';
|
|
||||||
} elseif ($recover) {
|
|
||||||
echo
|
|
||||||
'<div class="fieldset" role="main"><h2>' . __('Request a new password') . '</h2>' .
|
|
||||||
'<p><label for="user_id">' . __('Username:') . '</label> ' .
|
|
||||||
form::field('user_id', 20, 32,
|
|
||||||
[
|
|
||||||
'default' => html::escapeHTML($user_id),
|
|
||||||
'autocomplete' => 'username'
|
|
||||||
]
|
|
||||||
) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="user_email">' . __('Email:') . '</label> ' .
|
|
||||||
form::email('user_email',
|
|
||||||
[
|
|
||||||
'default' => html::escapeHTML($user_email),
|
|
||||||
'autocomplete' => 'email'
|
|
||||||
]
|
|
||||||
) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><input type="submit" value="' . __('recover') . '" />' .
|
|
||||||
form::hidden('recover', 1) . '</p>' .
|
|
||||||
'</div>' .
|
|
||||||
|
|
||||||
'<div id="issue">' .
|
|
||||||
'<p><a href="' . $core->adminurl->get('admin.auth') . '">' . __('Back to login screen') . '</a></p>' .
|
|
||||||
'</div>';
|
|
||||||
} elseif ($change_pwd) {
|
|
||||||
echo
|
|
||||||
'<div class="fieldset"><h2>' . __('Change your password') . '</h2>' .
|
|
||||||
'<p><label for="new_pwd">' . __('New password:') . '</label> ' .
|
|
||||||
form::password('new_pwd', 20, 255,
|
|
||||||
[
|
|
||||||
'autocomplete' => 'new-password'
|
|
||||||
]
|
|
||||||
) . '</p>' .
|
|
||||||
|
|
||||||
'<p><label for="new_pwd_c">' . __('Confirm password:') . '</label> ' .
|
|
||||||
form::password('new_pwd_c', 20, 255,
|
|
||||||
[
|
|
||||||
'autocomplete' => 'new-password'
|
|
||||||
]
|
|
||||||
) . '</p>' .
|
|
||||||
'</div>' .
|
|
||||||
|
|
||||||
'<p><input type="submit" value="' . __('change') . '" />' .
|
|
||||||
form::hidden('login_data', $login_data) . '</p>';
|
|
||||||
} else {
|
|
||||||
if (is_callable([$core->auth, 'authForm'])) {
|
|
||||||
echo $core->auth->authForm($user_id);
|
|
||||||
} else {
|
|
||||||
if ($safe_mode) {
|
|
||||||
echo '<div class="fieldset" role="main">';
|
|
||||||
echo '<h2>' . __('Safe mode login') . '</h2>';
|
|
||||||
echo
|
|
||||||
'<p class="form-note">' .
|
|
||||||
__('This mode allows you to login without activating any of your plugins. This may be useful to solve compatibility problems') . ' </p>' .
|
|
||||||
'<p class="form-note">' . __('Disable or delete any plugin suspected to cause trouble, then log out and log back in normally.') .
|
|
||||||
'</p>';
|
|
||||||
} else {
|
|
||||||
echo '<div class="fieldset" role="main">';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<p><label for="user_id">' . __('Username:') . '</label> ' .
|
|
||||||
form::field('user_id', 20, 32,
|
|
||||||
[
|
|
||||||
'default' => html::escapeHTML($user_id),
|
|
||||||
'autocomplete' => 'username'
|
|
||||||
]
|
|
||||||
) . '</p>' .
|
|
||||||
|
|
||||||
'<p><label for="user_pwd">' . __('Password:') . '</label> ' .
|
|
||||||
form::password('user_pwd', 20, 255,
|
|
||||||
[
|
|
||||||
'autocomplete' => 'current-password'
|
|
||||||
]
|
|
||||||
) . '</p>' .
|
|
||||||
|
|
||||||
'<p>' .
|
|
||||||
form::checkbox('user_remember', 1) .
|
|
||||||
'<label for="user_remember" class="classic">' .
|
|
||||||
__('Remember my ID on this device') . '</label></p>' .
|
|
||||||
|
|
||||||
'<p><input type="submit" value="' . __('log in') . '" class="login" /></p>';
|
|
||||||
|
|
||||||
if (!empty($_REQUEST['blog'])) {
|
|
||||||
echo form::hidden('blog', html::escapeHTML($_REQUEST['blog']));
|
|
||||||
}
|
|
||||||
if ($safe_mode) {
|
|
||||||
echo
|
|
||||||
form::hidden('safe_mode', 1) .
|
|
||||||
'</div>';
|
|
||||||
} else {
|
|
||||||
echo '</div>';
|
|
||||||
}
|
|
||||||
echo
|
|
||||||
'<p id="cookie_help" class="error">' . __('You must accept cookies in order to use the private area.') . '</p>';
|
|
||||||
|
|
||||||
echo '<div id="issue">';
|
|
||||||
|
|
||||||
if ($safe_mode) {
|
|
||||||
echo
|
|
||||||
'<p><a href="' . $core->adminurl->get('admin.auth') . '" id="normal_mode_link">' . __('Get back to normal authentication') . '</a></p>';
|
|
||||||
} else {
|
|
||||||
echo '<p id="more"><strong>' . __('Connection issue?') . '</strong></p>';
|
|
||||||
if ($core->auth->allowPassChange()) {
|
|
||||||
echo '<p><a href="' . $core->adminurl->get('admin.auth', ['recover' => 1]) . '">' . __('I forgot my password') . '</a></p>';
|
|
||||||
}
|
|
||||||
echo '<p><a href="' . $core->adminurl->get('admin.auth', ['safe_mode' => 1]) . '" id="safe_mode_link">' . __('I want to log in in safe mode') . '</a></p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '</div>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</form>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,113 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Backend
|
|
||||||
*
|
|
||||||
* @copyright Olivier Meunier & Association Dotclear
|
|
||||||
* @copyright GPL-2.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
|
||||||
|
|
||||||
dcPage::checkSuper();
|
|
||||||
|
|
||||||
$blog_id = '';
|
|
||||||
$blog_url = '';
|
|
||||||
$blog_name = '';
|
|
||||||
$blog_desc = '';
|
|
||||||
|
|
||||||
# Create a blog
|
|
||||||
if (!isset($_POST['id']) && (isset($_POST['create']))) {
|
|
||||||
$cur = $core->con->openCursor($core->prefix . 'blog');
|
|
||||||
$blog_id = $cur->blog_id = $_POST['blog_id'];
|
|
||||||
$blog_url = $cur->blog_url = $_POST['blog_url'];
|
|
||||||
$blog_name = $cur->blog_name = $_POST['blog_name'];
|
|
||||||
$blog_desc = $cur->blog_desc = $_POST['blog_desc'];
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
# --BEHAVIOR-- adminBeforeBlogCreate
|
|
||||||
$core->callBehavior('adminBeforeBlogCreate', $cur, $blog_id);
|
|
||||||
|
|
||||||
$core->addBlog($cur);
|
|
||||||
|
|
||||||
# Default settings and override some
|
|
||||||
$core->blogDefaults($cur->blog_id);
|
|
||||||
$blog_settings = new dcSettings($core, $cur->blog_id);
|
|
||||||
$blog_settings->addNamespace('system');
|
|
||||||
$blog_settings->system->put('lang', $core->auth->getInfo('user_lang'));
|
|
||||||
$blog_settings->system->put('blog_timezone', $core->auth->getInfo('user_tz'));
|
|
||||||
|
|
||||||
if (substr($blog_url, -1) == '?') {
|
|
||||||
$blog_settings->system->put('url_scan', 'query_string');
|
|
||||||
} else {
|
|
||||||
$blog_settings->system->put('url_scan', 'path_info');
|
|
||||||
}
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminAfterBlogCreate
|
|
||||||
$core->callBehavior('adminAfterBlogCreate', $cur, $blog_id, $blog_settings);
|
|
||||||
dcPage::addSuccessNotice(sprintf(__('Blog "%s" successfully created'), html::escapeHTML($cur->blog_name)));
|
|
||||||
$core->adminurl->redirect("admin.blog", ['id' => $cur->blog_id]);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($_REQUEST['id'])) {
|
|
||||||
$edit_blog_mode = true;
|
|
||||||
include dirname(__FILE__) . '/blog_pref.php';
|
|
||||||
} else {
|
|
||||||
dcPage::open(__('New blog'), dcPage::jsConfirmClose('blog-form'),
|
|
||||||
dcPage::breadcrumb(
|
|
||||||
[
|
|
||||||
__('System') => '',
|
|
||||||
__('Blogs') => $core->adminurl->get("admin.blogs"),
|
|
||||||
__('New blog') => ''
|
|
||||||
])
|
|
||||||
);
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<form action="' . $core->adminurl->get("admin.blog") . '" method="post" id="blog-form">' .
|
|
||||||
|
|
||||||
'<div>' . $core->formNonce() . '</div>' .
|
|
||||||
'<p><label class="required" for="blog_id"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Blog ID:') . '</label> ' .
|
|
||||||
form::field('blog_id', 30, 32,
|
|
||||||
[
|
|
||||||
'default' => html::escapeHTML($blog_id),
|
|
||||||
'extra_html' => 'required placeholder="' . __('Blog ID') . '"'
|
|
||||||
]
|
|
||||||
) . '</p>' .
|
|
||||||
'<p class="form-note">' . __('At least 2 characters using letters, numbers or symbols.') . '</p> ';
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<p><label class="required" for="blog_name"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Blog name:') . '</label> ' .
|
|
||||||
form::field('blog_name', 30, 255,
|
|
||||||
[
|
|
||||||
'default' => html::escapeHTML($blog_name),
|
|
||||||
'extra_html' => 'required placeholder="' . __('Blog name') . '" lang="' . $core->auth->getInfo('user_lang') . '" ' .
|
|
||||||
'spellcheck="true"'
|
|
||||||
]
|
|
||||||
) . '</p>' .
|
|
||||||
|
|
||||||
'<p><label class="required" for="blog_url"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Blog URL:') . '</label> ' .
|
|
||||||
form::url('blog_url',
|
|
||||||
[
|
|
||||||
'size' => 30,
|
|
||||||
'default' => html::escapeHTML($blog_url),
|
|
||||||
'extra_html' => 'required placeholder="' . __('Blog URL') . '"'
|
|
||||||
]
|
|
||||||
) . '</p>' .
|
|
||||||
|
|
||||||
'<p class="area"><label for="blog_desc">' . __('Blog description:') . '</label> ' .
|
|
||||||
form::textarea('blog_desc', 60, 5,
|
|
||||||
[
|
|
||||||
'default' => html::escapeHTML($blog_desc),
|
|
||||||
'extra_html' => 'lang="' . $core->auth->getInfo('user_lang') . '" spellcheck="true"'
|
|
||||||
]) . '</p>' .
|
|
||||||
|
|
||||||
'<p><input type="submit" accesskey="s" name="create" value="' . __('Create') . '" /></p>' .
|
|
||||||
'</form>';
|
|
||||||
|
|
||||||
dcPage::helpBlock('core_blog_new');
|
|
||||||
dcPage::close();
|
|
||||||
}
|
|
||||||
@ -1,74 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Backend
|
|
||||||
*
|
|
||||||
* @copyright Olivier Meunier & Association Dotclear
|
|
||||||
* @copyright GPL-2.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
|
||||||
|
|
||||||
dcPage::checkSuper();
|
|
||||||
|
|
||||||
$blog_id = '';
|
|
||||||
$blog_name = '';
|
|
||||||
|
|
||||||
if (!empty($_POST['blog_id'])) {
|
|
||||||
try {
|
|
||||||
$rs = $core->getBlog($_POST['blog_id']);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($rs->isEmpty()) {
|
|
||||||
$core->error->add(__('No such blog ID'));
|
|
||||||
} else {
|
|
||||||
$blog_id = $rs->blog_id;
|
|
||||||
$blog_name = $rs->blog_name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Delete the blog
|
|
||||||
if (!$core->error->flag() && $blog_id && !empty($_POST['del'])) {
|
|
||||||
if (!$core->auth->checkPassword($_POST['pwd'])) {
|
|
||||||
$core->error->add(__('Password verification failed'));
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
$core->delBlog($blog_id);
|
|
||||||
dcPage::addSuccessNotice(sprintf(__('Blog "%s" successfully deleted'), html::escapeHTML($blog_name)));
|
|
||||||
|
|
||||||
$core->adminurl->redirect("admin.blogs");
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dcPage::open(__('Delete a blog'), '',
|
|
||||||
dcPage::breadcrumb(
|
|
||||||
[
|
|
||||||
__('System') => '',
|
|
||||||
__('Blogs') => $core->adminurl->get("admin.blogs"),
|
|
||||||
__('Delete a blog') => ''
|
|
||||||
])
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!$core->error->flag()) {
|
|
||||||
echo
|
|
||||||
'<div class="warning-msg"><p><strong>' . __('Warning') . '</strong></p>' .
|
|
||||||
'<p>' . sprintf(__('You are about to delete the blog %s. Every entry, comment and category will be deleted.'),
|
|
||||||
'<strong>' . $blog_id . ' (' . $blog_name . ')</strong>') . '</p></div>' .
|
|
||||||
'<p>' . __('Please give your password to confirm the blog deletion.') . '</p>';
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<form action="' . $core->adminurl->get("admin.blog.del") . '" method="post">' .
|
|
||||||
'<div>' . $core->formNonce() . '</div>' .
|
|
||||||
'<p><label for="pwd">' . __('Your password:') . '</label> ' .
|
|
||||||
form::password('pwd', 20, 255, ['autocomplete' => 'current-password']) . '</p>' .
|
|
||||||
'<p><input type="submit" class="delete" name="del" value="' . __('Delete this blog') . '" />' .
|
|
||||||
form::hidden('blog_id', $blog_id) . '</p>' .
|
|
||||||
'</form>';
|
|
||||||
}
|
|
||||||
|
|
||||||
dcPage::close();
|
|
||||||
@ -1,907 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Backend
|
|
||||||
*
|
|
||||||
* @copyright Olivier Meunier & Association Dotclear
|
|
||||||
* @copyright GPL-2.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
$standalone = !isset($edit_blog_mode);
|
|
||||||
|
|
||||||
$blog_id = false;
|
|
||||||
|
|
||||||
if ($standalone) {
|
|
||||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
|
||||||
dcPage::check('admin');
|
|
||||||
$blog_id = $core->blog->id;
|
|
||||||
$blog_status = $core->blog->status;
|
|
||||||
$blog_name = $core->blog->name;
|
|
||||||
$blog_desc = $core->blog->desc;
|
|
||||||
$blog_settings = $core->blog->settings;
|
|
||||||
$blog_url = $core->blog->url;
|
|
||||||
|
|
||||||
$action = $core->adminurl->get("admin.blog.pref");
|
|
||||||
$redir = $core->adminurl->get("admin.blog.pref");
|
|
||||||
} else {
|
|
||||||
dcPage::checkSuper();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (empty($_REQUEST['id'])) {
|
|
||||||
throw new Exception(__('No given blog id.'));
|
|
||||||
}
|
|
||||||
$rs = $core->getBlog($_REQUEST['id']);
|
|
||||||
|
|
||||||
if (!$rs) {
|
|
||||||
throw new Exception(__('No such blog.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$blog_id = $rs->blog_id;
|
|
||||||
$blog_status = $rs->blog_status;
|
|
||||||
$blog_name = $rs->blog_name;
|
|
||||||
$blog_desc = $rs->blog_desc;
|
|
||||||
$blog_settings = new dcSettings($core, $blog_id);
|
|
||||||
$blog_url = $rs->blog_url;
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
$action = $core->adminurl->get("admin.blog");
|
|
||||||
$redir = $core->adminurl->get("admin.blog", ['id' => "%s"], '&', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Language codes
|
|
||||||
$lang_combo = dcAdminCombos::getAdminLangsCombo();
|
|
||||||
|
|
||||||
# Status combo
|
|
||||||
$status_combo = dcAdminCombos::getBlogStatusescombo();
|
|
||||||
|
|
||||||
# Date format combo
|
|
||||||
$now = time();
|
|
||||||
$date_formats = $blog_settings->system->date_formats;
|
|
||||||
$time_formats = $blog_settings->system->time_formats;
|
|
||||||
$date_formats_combo = ['' => ''];
|
|
||||||
foreach ($date_formats as $format) {
|
|
||||||
$date_formats_combo[dt::str($format, $now)] = $format;
|
|
||||||
}
|
|
||||||
$time_formats_combo = ['' => ''];
|
|
||||||
foreach ($time_formats as $format) {
|
|
||||||
$time_formats_combo[dt::str($format, $now)] = $format;
|
|
||||||
}
|
|
||||||
|
|
||||||
# URL scan modes
|
|
||||||
$url_scan_combo = [
|
|
||||||
'PATH_INFO' => 'path_info',
|
|
||||||
'QUERY_STRING' => 'query_string'
|
|
||||||
];
|
|
||||||
|
|
||||||
# Post URL combo
|
|
||||||
$post_url_combo = [
|
|
||||||
__('year/month/day/title') => '{y}/{m}/{d}/{t}',
|
|
||||||
__('year/month/title') => '{y}/{m}/{t}',
|
|
||||||
__('year/title') => '{y}/{t}',
|
|
||||||
__('title') => '{t}',
|
|
||||||
__('post id/title') => '{id}/{t}',
|
|
||||||
__('post id') => '{id}'
|
|
||||||
];
|
|
||||||
if (!in_array($blog_settings->system->post_url_format, $post_url_combo)) {
|
|
||||||
$post_url_combo[html::escapeHTML($blog_settings->system->post_url_format)] = html::escapeHTML($blog_settings->system->post_url_format);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Note title tag combo
|
|
||||||
$note_title_tag_combo = [
|
|
||||||
__('H4') => 0,
|
|
||||||
__('H3') => 1,
|
|
||||||
__('P') => 2
|
|
||||||
];
|
|
||||||
|
|
||||||
# Image title combo
|
|
||||||
$img_title_combo = [
|
|
||||||
__('(none)') => '',
|
|
||||||
__('Title') => 'Title ;; separator(, )',
|
|
||||||
__('Title, Date') => 'Title ;; Date(%b %Y) ;; separator(, )',
|
|
||||||
__('Title, Country, Date') => 'Title ;; Country ;; Date(%b %Y) ;; separator(, )',
|
|
||||||
__('Title, City, Country, Date') => 'Title ;; City ;; Country ;; Date(%b %Y) ;; separator(, )'
|
|
||||||
];
|
|
||||||
if (!in_array($blog_settings->system->media_img_title_pattern, $img_title_combo)) {
|
|
||||||
$img_title_combo[html::escapeHTML($blog_settings->system->media_img_title_pattern)] = html::escapeHTML($blog_settings->system->media_img_title_pattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Image default size combo
|
|
||||||
$img_default_size_combo = [];
|
|
||||||
try {
|
|
||||||
$media = new dcMedia($core);
|
|
||||||
$img_default_size_combo[__('original')] = 'o';
|
|
||||||
foreach ($media->thumb_sizes as $code => $size) {
|
|
||||||
$img_default_size_combo[__($size[2])] = $code;
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
# Image default alignment combo
|
|
||||||
$img_default_alignment_combo = [
|
|
||||||
__('None') => 'none',
|
|
||||||
__('Left') => 'left',
|
|
||||||
__('Right') => 'right',
|
|
||||||
__('Center') => 'center'
|
|
||||||
];
|
|
||||||
|
|
||||||
# Image default legend and title combo
|
|
||||||
$img_default_legend_combo = [
|
|
||||||
__('Legend and title') => 'legend',
|
|
||||||
__('Title') => 'title',
|
|
||||||
__('None') => 'none'
|
|
||||||
];
|
|
||||||
|
|
||||||
# Robots policy options
|
|
||||||
$robots_policy_options = [
|
|
||||||
'INDEX,FOLLOW' => __("I would like search engines and archivers to index and archive my blog's content."),
|
|
||||||
'INDEX,FOLLOW,NOARCHIVE' => __("I would like search engines and archivers to index but not archive my blog's content."),
|
|
||||||
'NOINDEX,NOFOLLOW,NOARCHIVE' => __("I would like to prevent search engines and archivers from indexing or archiving my blog's content.")
|
|
||||||
];
|
|
||||||
|
|
||||||
# jQuery available versions
|
|
||||||
$jquery_root = dirname(__FILE__) . '/../inc/js/jquery';
|
|
||||||
$jquery_versions_combo = [__('Default') . ' (' . DC_DEFAULT_JQUERY . ')' => ''];
|
|
||||||
if (is_dir($jquery_root) && is_readable($jquery_root)) {
|
|
||||||
if (($d = @dir($jquery_root)) !== false) {
|
|
||||||
while (($entry = $d->read()) !== false) {
|
|
||||||
if ($entry != '.' && $entry != '..' && substr($entry, 0, 1) != '.' && is_dir($jquery_root . '/' . $entry)) {
|
|
||||||
if ($entry != DC_DEFAULT_JQUERY) {
|
|
||||||
$jquery_versions_combo[$entry] = $entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Update a blog
|
|
||||||
if ($blog_id && !empty($_POST) && $core->auth->check('admin', $blog_id)) {
|
|
||||||
$cur = $core->con->openCursor($core->prefix . 'blog');
|
|
||||||
$cur->blog_id = $_POST['blog_id'];
|
|
||||||
$cur->blog_url = preg_replace('/\?+$/', '?', $_POST['blog_url']);
|
|
||||||
$cur->blog_name = $_POST['blog_name'];
|
|
||||||
$cur->blog_desc = $_POST['blog_desc'];
|
|
||||||
|
|
||||||
if ($core->auth->isSuperAdmin() && in_array($_POST['blog_status'], $status_combo)) {
|
|
||||||
$cur->blog_status = (int) $_POST['blog_status'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$media_img_t_size = (integer) $_POST['media_img_t_size'];
|
|
||||||
if ($media_img_t_size < 0) {$media_img_t_size = 100;}
|
|
||||||
|
|
||||||
$media_img_s_size = (integer) $_POST['media_img_s_size'];
|
|
||||||
if ($media_img_s_size < 0) {$media_img_s_size = 240;}
|
|
||||||
|
|
||||||
$media_img_m_size = (integer) $_POST['media_img_m_size'];
|
|
||||||
if ($media_img_m_size < 0) {$media_img_m_size = 448;}
|
|
||||||
|
|
||||||
$media_video_width = (integer) $_POST['media_video_width'];
|
|
||||||
if ($media_video_width < 0) {$media_video_width = 400;}
|
|
||||||
|
|
||||||
$media_video_height = (integer) $_POST['media_video_height'];
|
|
||||||
if ($media_video_height < 0) {$media_video_height = 300;}
|
|
||||||
|
|
||||||
$nb_post_for_home = abs((integer) $_POST['nb_post_for_home']);
|
|
||||||
if ($nb_post_for_home < 1) {$nb_post_for_home = 1;}
|
|
||||||
|
|
||||||
$nb_post_per_page = abs((integer) $_POST['nb_post_per_page']);
|
|
||||||
if ($nb_post_per_page < 1) {$nb_post_per_page = 1;}
|
|
||||||
|
|
||||||
$nb_post_per_feed = abs((integer) $_POST['nb_post_per_feed']);
|
|
||||||
if ($nb_post_per_feed < 1) {$nb_post_per_feed = 1;}
|
|
||||||
|
|
||||||
$nb_comment_per_feed = abs((integer) $_POST['nb_comment_per_feed']);
|
|
||||||
if ($nb_comment_per_feed < 1) {$nb_comment_per_feed = 1;}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if ($cur->blog_id != null && $cur->blog_id != $blog_id) {
|
|
||||||
$rs = $core->getBlog($cur->blog_id);
|
|
||||||
|
|
||||||
if ($rs) {
|
|
||||||
throw new Exception(__('This blog ID is already used.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminBeforeBlogUpdate
|
|
||||||
$core->callBehavior('adminBeforeBlogUpdate', $cur, $blog_id);
|
|
||||||
|
|
||||||
if (!preg_match('/^[a-z]{2}(-[a-z]{2})?$/', $_POST['lang'])) {
|
|
||||||
throw new Exception(__('Invalid language code'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$core->updBlog($blog_id, $cur);
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminAfterBlogUpdate
|
|
||||||
$core->callBehavior('adminAfterBlogUpdate', $cur, $blog_id);
|
|
||||||
|
|
||||||
if ($cur->blog_id != null && $cur->blog_id != $blog_id) {
|
|
||||||
if ($blog_id == $core->blog->id) {
|
|
||||||
$core->setBlog($cur->blog_id);
|
|
||||||
$_SESSION['sess_blog_id'] = $cur->blog_id;
|
|
||||||
$blog_settings = $core->blog->settings;
|
|
||||||
} else {
|
|
||||||
$blog_settings = new dcSettings($core, $cur->blog_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
$blog_id = $cur->blog_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
$blog_settings->addNameSpace('system');
|
|
||||||
|
|
||||||
$blog_settings->system->put('editor', $_POST['editor']);
|
|
||||||
$blog_settings->system->put('copyright_notice', $_POST['copyright_notice']);
|
|
||||||
$blog_settings->system->put('post_url_format', $_POST['post_url_format']);
|
|
||||||
$blog_settings->system->put('lang', $_POST['lang']);
|
|
||||||
$blog_settings->system->put('blog_timezone', $_POST['blog_timezone']);
|
|
||||||
$blog_settings->system->put('date_format', $_POST['date_format']);
|
|
||||||
$blog_settings->system->put('time_format', $_POST['time_format']);
|
|
||||||
$blog_settings->system->put('comments_ttl', abs((integer) $_POST['comments_ttl']));
|
|
||||||
$blog_settings->system->put('trackbacks_ttl', abs((integer) $_POST['trackbacks_ttl']));
|
|
||||||
$blog_settings->system->put('allow_comments', !empty($_POST['allow_comments']));
|
|
||||||
$blog_settings->system->put('allow_trackbacks', !empty($_POST['allow_trackbacks']));
|
|
||||||
$blog_settings->system->put('comments_pub', empty($_POST['comments_pub']));
|
|
||||||
$blog_settings->system->put('trackbacks_pub', empty($_POST['trackbacks_pub']));
|
|
||||||
$blog_settings->system->put('comments_nofollow', !empty($_POST['comments_nofollow']));
|
|
||||||
$blog_settings->system->put('wiki_comments', !empty($_POST['wiki_comments']));
|
|
||||||
$blog_settings->system->put('comment_preview_optional', !empty($_POST['comment_preview_optional']));
|
|
||||||
$blog_settings->system->put('enable_xmlrpc', !empty($_POST['enable_xmlrpc']));
|
|
||||||
$blog_settings->system->put('note_title_tag', $_POST['note_title_tag']);
|
|
||||||
$blog_settings->system->put('nb_post_for_home', $nb_post_for_home);
|
|
||||||
$blog_settings->system->put('nb_post_per_page', $nb_post_per_page);
|
|
||||||
$blog_settings->system->put('use_smilies', !empty($_POST['use_smilies']));
|
|
||||||
$blog_settings->system->put('no_search', !empty($_POST['no_search']));
|
|
||||||
$blog_settings->system->put('inc_subcats', !empty($_POST['inc_subcats']));
|
|
||||||
$blog_settings->system->put('media_img_t_size', $media_img_t_size);
|
|
||||||
$blog_settings->system->put('media_img_s_size', $media_img_s_size);
|
|
||||||
$blog_settings->system->put('media_img_m_size', $media_img_m_size);
|
|
||||||
$blog_settings->system->put('media_video_width', $media_video_width);
|
|
||||||
$blog_settings->system->put('media_video_height', $media_video_height);
|
|
||||||
$blog_settings->system->put('media_img_title_pattern', $_POST['media_img_title_pattern']);
|
|
||||||
$blog_settings->system->put('media_img_use_dto_first', !empty($_POST['media_img_use_dto_first']));
|
|
||||||
$blog_settings->system->put('media_img_no_date_alone', !empty($_POST['media_img_no_date_alone']));
|
|
||||||
$blog_settings->system->put('media_img_default_size', $_POST['media_img_default_size']);
|
|
||||||
$blog_settings->system->put('media_img_default_alignment', $_POST['media_img_default_alignment']);
|
|
||||||
$blog_settings->system->put('media_img_default_link', !empty($_POST['media_img_default_link']));
|
|
||||||
$blog_settings->system->put('media_img_default_legend', $_POST['media_img_default_legend']);
|
|
||||||
$blog_settings->system->put('nb_post_per_feed', $nb_post_per_feed);
|
|
||||||
$blog_settings->system->put('nb_comment_per_feed', $nb_comment_per_feed);
|
|
||||||
$blog_settings->system->put('short_feed_items', !empty($_POST['short_feed_items']));
|
|
||||||
if (isset($_POST['robots_policy'])) {
|
|
||||||
$blog_settings->system->put('robots_policy', $_POST['robots_policy']);
|
|
||||||
}
|
|
||||||
$blog_settings->system->put('jquery_needed', !empty($_POST['jquery_needed']));
|
|
||||||
$blog_settings->system->put('jquery_version', $_POST['jquery_version']);
|
|
||||||
$blog_settings->system->put('prevents_clickjacking', !empty($_POST['prevents_clickjacking']));
|
|
||||||
$blog_settings->system->put('static_home', !empty($_POST['static_home']));
|
|
||||||
$blog_settings->system->put('static_home_url', $_POST['static_home_url']);
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminBeforeBlogSettingsUpdate
|
|
||||||
$core->callBehavior('adminBeforeBlogSettingsUpdate', $blog_settings);
|
|
||||||
|
|
||||||
if ($core->auth->isSuperAdmin() && in_array($_POST['url_scan'], $url_scan_combo)) {
|
|
||||||
$blog_settings->system->put('url_scan', $_POST['url_scan']);
|
|
||||||
}
|
|
||||||
dcPage::addSuccessNotice(__('Blog has been successfully updated.'));
|
|
||||||
|
|
||||||
http::redirect(sprintf($redir, $blog_id));
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display
|
|
||||||
|
|
||||||
if ($standalone) {
|
|
||||||
$breadcrumb = dcPage::breadcrumb(
|
|
||||||
[
|
|
||||||
html::escapeHTML($blog_name) => '',
|
|
||||||
__('Blog settings') => ''
|
|
||||||
]
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$breadcrumb = dcPage::breadcrumb(
|
|
||||||
[
|
|
||||||
__('System') => '',
|
|
||||||
__('Blogs') => $core->adminurl->get("admin.blogs"),
|
|
||||||
__('Blog settings') . ' : ' . html::escapeHTML($blog_name) => ''
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$desc_editor = $core->auth->getOption('editor');
|
|
||||||
$rte_flag = true;
|
|
||||||
$rte_flags = @$core->auth->user_prefs->interface->rte_flags;
|
|
||||||
if (is_array($rte_flags) && in_array('blog_descr', $rte_flags)) {
|
|
||||||
$rte_flag = $rte_flags['blog_descr'];
|
|
||||||
}
|
|
||||||
|
|
||||||
dcPage::open(__('Blog settings'),
|
|
||||||
dcPage::jsJson('blog_pref', [
|
|
||||||
'warning_path_info' => __('Warning: except for special configurations, it is generally advised to have a trailing "/" in your blog URL in PATH_INFO mode.'),
|
|
||||||
'warning_query_string' => __('Warning: except for special configurations, it is generally advised to have a trailing "?" in your blog URL in QUERY_STRING mode.')
|
|
||||||
]) .
|
|
||||||
dcPage::jsConfirmClose('blog-form') .
|
|
||||||
($rte_flag ? $core->callBehavior('adminPostEditor', $desc_editor['xhtml'], 'blog_desc', ['#blog_desc'], 'xhtml') : '') .
|
|
||||||
dcPage::jsLoad('js/_blog_pref.js') .
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminBlogPreferencesHeaders
|
|
||||||
$core->callBehavior('adminBlogPreferencesHeaders') .
|
|
||||||
|
|
||||||
dcPage::jsPageTabs(),
|
|
||||||
$breadcrumb
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($blog_id) {
|
|
||||||
if (!empty($_GET['add'])) {
|
|
||||||
dcPage::success(__('Blog has been successfully created.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($_GET['upd'])) {
|
|
||||||
dcPage::success(__('Blog has been successfully updated.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<div class="multi-part" id="params" title="' . __('Parameters') . '">' .
|
|
||||||
'<div id="standard-pref"><h3>' . __('Blog parameters') . '</h3>' .
|
|
||||||
'<form action="' . $action . '" method="post" id="blog-form">';
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<div class="fieldset"><h4>' . __('Blog details') . '</h4>' .
|
|
||||||
$core->formNonce();
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<p><label for="blog_name" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Blog name:') . '</label>' .
|
|
||||||
form::field('blog_name', 30, 255,
|
|
||||||
[
|
|
||||||
'default' => html::escapeHTML($blog_name),
|
|
||||||
'extra_html' => 'required placeholder="' . __('Blog name') . ' lang="' . $blog_settings->system->lang .
|
|
||||||
'" spellcheck="true"'
|
|
||||||
]
|
|
||||||
) . '</p>';
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<p class="area"><label for="blog_desc">' . __('Blog description:') . '</label>' .
|
|
||||||
form::textarea('blog_desc', 60, 5,
|
|
||||||
[
|
|
||||||
'default' => html::escapeHTML($blog_desc),
|
|
||||||
'extra_html' => 'lang="' . $blog_settings->system->lang . '" spellcheck="true"'
|
|
||||||
]) . '</p>';
|
|
||||||
|
|
||||||
if ($core->auth->isSuperAdmin()) {
|
|
||||||
echo
|
|
||||||
'<p><label for="blog_status">' . __('Blog status:') . '</label>' .
|
|
||||||
form::combo('blog_status', $status_combo, $blog_status) . '</p>';
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
Only super admins can change the blog ID and URL, but we need to pass
|
|
||||||
their values to the POST request via hidden html input values so as
|
|
||||||
to allow admins to update other settings.
|
|
||||||
Otherwise dcCore::getBlogCursor() throws an exception.
|
|
||||||
*/
|
|
||||||
echo
|
|
||||||
form::hidden('blog_id', html::escapeHTML($blog_id)) .
|
|
||||||
form::hidden('blog_url', html::escapeHTML($blog_url));
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '</div>';
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<div class="fieldset"><h4>' . __('Blog configuration') . '</h4>' .
|
|
||||||
|
|
||||||
'<p><label for="editor">' . __('Blog editor name:') . '</label>' .
|
|
||||||
form::field('editor', 30, 255, html::escapeHTML($blog_settings->system->editor)) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="lang">' . __('Default language:') . '</label>' .
|
|
||||||
form::combo('lang', $lang_combo, $blog_settings->system->lang, 'l10n') .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="blog_timezone">' . __('Blog timezone:') . '</label>' .
|
|
||||||
form::combo('blog_timezone', dt::getZones(true, true), html::escapeHTML($blog_settings->system->blog_timezone)) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="copyright_notice">' . __('Copyright notice:') . '</label>' .
|
|
||||||
form::field('copyright_notice', 30, 255,
|
|
||||||
[
|
|
||||||
'default' => html::escapeHTML($blog_settings->system->copyright_notice),
|
|
||||||
'extra_html' => 'lang="' . $blog_settings->system->lang . '" spellcheck="true"'
|
|
||||||
]) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'</div>';
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<div class="fieldset"><h4>' . __('Comments and trackbacks') . '</h4>' .
|
|
||||||
|
|
||||||
'<div class="two-cols">' .
|
|
||||||
|
|
||||||
'<div class="col">' .
|
|
||||||
'<p><label for="allow_comments" class="classic">' .
|
|
||||||
form::checkbox('allow_comments', '1', $blog_settings->system->allow_comments) .
|
|
||||||
__('Accept comments') . '</label></p>' .
|
|
||||||
'<p><label for="comments_pub" class="classic">' .
|
|
||||||
form::checkbox('comments_pub', '1', !$blog_settings->system->comments_pub) .
|
|
||||||
__('Moderate comments') . '</label></p>' .
|
|
||||||
'<p><label for="comments_ttl" class="classic">' . sprintf(__('Leave comments open for %s days') . '.',
|
|
||||||
form::number('comments_ttl', [
|
|
||||||
'min' => 0,
|
|
||||||
'max' => 999,
|
|
||||||
'default' => $blog_settings->system->comments_ttl]
|
|
||||||
)) .
|
|
||||||
'</label></p>' .
|
|
||||||
'<p class="form-note">' . __('No limit: leave blank.') . '</p>' .
|
|
||||||
'<p><label for="wiki_comments" class="classic">' .
|
|
||||||
form::checkbox('wiki_comments', '1', $blog_settings->system->wiki_comments) .
|
|
||||||
__('Wiki syntax for comments') . '</label></p>' .
|
|
||||||
'<p><label for="comment_preview_optional" class="classic">' .
|
|
||||||
form::checkbox('comment_preview_optional', '1', $blog_settings->system->comment_preview_optional) .
|
|
||||||
__('Preview of comment before submit is not mandatory') . '</label></p>' .
|
|
||||||
'</div>' .
|
|
||||||
|
|
||||||
'<div class="col">' .
|
|
||||||
'<p><label for="allow_trackbacks" class="classic">' .
|
|
||||||
form::checkbox('allow_trackbacks', '1', $blog_settings->system->allow_trackbacks) .
|
|
||||||
__('Accept trackbacks') . '</label></p>' .
|
|
||||||
'<p><label for="trackbacks_pub" class="classic">' .
|
|
||||||
form::checkbox('trackbacks_pub', '1', !$blog_settings->system->trackbacks_pub) .
|
|
||||||
__('Moderate trackbacks') . '</label></p>' .
|
|
||||||
'<p><label for="trackbacks_ttl" class="classic">' . sprintf(__('Leave trackbacks open for %s days') . '.',
|
|
||||||
form::number('trackbacks_ttl', [
|
|
||||||
'min' => 0,
|
|
||||||
'max' => 999,
|
|
||||||
'default' => $blog_settings->system->trackbacks_ttl]
|
|
||||||
)) .
|
|
||||||
'</label></p>' .
|
|
||||||
'<p class="form-note">' . __('No limit: leave blank.') . '</p>' .
|
|
||||||
'<p><label for="comments_nofollow" class="classic">' .
|
|
||||||
form::checkbox('comments_nofollow', '1', $blog_settings->system->comments_nofollow) .
|
|
||||||
__('Add "nofollow" relation on comments and trackbacks links') . '</label></p>' .
|
|
||||||
'</div>' .
|
|
||||||
'<br class="clear" />' . //Opera sucks
|
|
||||||
|
|
||||||
'</div>' .
|
|
||||||
'<br class="clear" />' . //Opera sucks
|
|
||||||
'</div>';
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<div class="fieldset"><h4>' . __('Blog presentation') . '</h4>' .
|
|
||||||
'<div class="two-cols">' .
|
|
||||||
'<div class="col">' .
|
|
||||||
'<p><label for="date_format">' . __('Date format:') . '</label> ' .
|
|
||||||
form::field('date_format', 30, 255, html::escapeHTML($blog_settings->system->date_format)) .
|
|
||||||
form::combo('date_format_select', $date_formats_combo, ['extra_html' => 'title="' . __('Pattern of date') . '"']) .
|
|
||||||
'</p>' .
|
|
||||||
'<p class="chosen form-note">' . __('Sample:') . ' ' . dt::str(html::escapeHTML($blog_settings->system->date_format)) . '</p>' .
|
|
||||||
|
|
||||||
'<p><label for="time_format">' . __('Time format:') . '</label>' .
|
|
||||||
form::field('time_format', 30, 255, html::escapeHTML($blog_settings->system->time_format)) .
|
|
||||||
form::combo('time_format_select', $time_formats_combo, ['extra_html' => 'title="' . __('Pattern of time') . '"']) .
|
|
||||||
'</p>' .
|
|
||||||
'<p class="chosen form-note">' . __('Sample:') . ' ' . dt::str(html::escapeHTML($blog_settings->system->time_format)) . '</p>' .
|
|
||||||
|
|
||||||
'<p><label for="use_smilies" class="classic">' .
|
|
||||||
form::checkbox('use_smilies', '1', $blog_settings->system->use_smilies) .
|
|
||||||
__('Display smilies on entries and comments') . '</label></p>' .
|
|
||||||
|
|
||||||
'<p><label for="no_search" class="classic">' .
|
|
||||||
form::checkbox('no_search', '1', $blog_settings->system->no_search) .
|
|
||||||
__('Disable internal search system') . '</label></p>' .
|
|
||||||
|
|
||||||
'</div>' .
|
|
||||||
|
|
||||||
'<div class="col">' .
|
|
||||||
|
|
||||||
'<p><label for="nb_post_for_home" class="classic">' . sprintf(__('Display %s entries on first page'),
|
|
||||||
form::number('nb_post_for_home', [
|
|
||||||
'min' => 1,
|
|
||||||
'max' => 999,
|
|
||||||
'default' => $blog_settings->system->nb_post_for_home]
|
|
||||||
)) .
|
|
||||||
'</label></p>' .
|
|
||||||
|
|
||||||
'<p><label for="nb_post_per_page" class="classic">' . sprintf(__('Display %s entries per page'),
|
|
||||||
form::number('nb_post_per_page', [
|
|
||||||
'min' => 1,
|
|
||||||
'max' => 999,
|
|
||||||
'default' => $blog_settings->system->nb_post_per_page]
|
|
||||||
)) .
|
|
||||||
'</label></p>' .
|
|
||||||
|
|
||||||
'<p><label for="nb_post_per_feed" class="classic">' . sprintf(__('Display %s entries per feed'),
|
|
||||||
form::number('nb_post_per_feed', [
|
|
||||||
'min' => 1,
|
|
||||||
'max' => 999,
|
|
||||||
'default' => $blog_settings->system->nb_post_per_feed]
|
|
||||||
)) .
|
|
||||||
'</label></p>' .
|
|
||||||
|
|
||||||
'<p><label for="nb_comment_per_feed" class="classic">' . sprintf(__('Display %s comments per feed'),
|
|
||||||
form::number('nb_comment_per_feed', [
|
|
||||||
'min' => 1,
|
|
||||||
'max' => 999,
|
|
||||||
'default' => $blog_settings->system->nb_comment_per_feed]
|
|
||||||
)) .
|
|
||||||
'</label></p>' .
|
|
||||||
|
|
||||||
'<p><label for="short_feed_items" class="classic">' .
|
|
||||||
form::checkbox('short_feed_items', '1', $blog_settings->system->short_feed_items) .
|
|
||||||
__('Truncate feeds') . '</label></p>' .
|
|
||||||
|
|
||||||
'<p><label for="inc_subcats" class="classic">' .
|
|
||||||
form::checkbox('inc_subcats', '1', $blog_settings->system->inc_subcats) .
|
|
||||||
__('Include sub-categories in category page and category posts feed') . '</label></p>' .
|
|
||||||
'</div>' .
|
|
||||||
'</div>' .
|
|
||||||
'<br class="clear" />' . //Opera sucks
|
|
||||||
|
|
||||||
'<hr />' .
|
|
||||||
|
|
||||||
'<p><label for="static_home" class="classic">' .
|
|
||||||
form::checkbox('static_home', '1', $blog_settings->system->static_home) .
|
|
||||||
__('Display an entry as static home page') . '</label></p>' .
|
|
||||||
|
|
||||||
'<p><label for="static_home_url" class="classic">' . __('Entry URL (its content will be used for the static home page):') . '</label> ' .
|
|
||||||
form::field('static_home_url', 30, 255, html::escapeHTML($blog_settings->system->static_home_url)) .
|
|
||||||
' <button type="button" id="static_home_url_selector">' . __('Choose an entry') . '</button>' .
|
|
||||||
'</p>' .
|
|
||||||
'<p class="form-note">' . __('Leave empty to use the default presentation.') . '</p> ' .
|
|
||||||
|
|
||||||
'</div>';
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<div class="fieldset"><h4 id="medias-settings">' . __('Media and images') . '</h4>' .
|
|
||||||
'<p class="form-note warning">' .
|
|
||||||
__('Please note that if you change current settings bellow, they will now apply to all new images in the media manager.') .
|
|
||||||
' ' . __('Be carefull if you share it with other blogs in your installation.') . '<br />' .
|
|
||||||
__('Set -1 to use the default size, set 0 to ignore this thumbnail size (images only).') . '</p>' .
|
|
||||||
|
|
||||||
'<div class="two-cols">' .
|
|
||||||
'<div class="col">' .
|
|
||||||
'<h5>' . __('Generated image sizes (max dimension in pixels)') . '</h5>' .
|
|
||||||
'<p class="field"><label for="media_img_t_size">' . __('Thumbnail') . '</label> ' .
|
|
||||||
form::number('media_img_t_size', [
|
|
||||||
'min' => -1,
|
|
||||||
'max' => 999,
|
|
||||||
'default' => $blog_settings->system->media_img_t_size
|
|
||||||
]) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p class="field"><label for="media_img_s_size">' . __('Small') . '</label> ' .
|
|
||||||
form::number('media_img_s_size', [
|
|
||||||
'min' => -1,
|
|
||||||
'max' => 999,
|
|
||||||
'default' => $blog_settings->system->media_img_s_size
|
|
||||||
]) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p class="field"><label for="media_img_m_size">' . __('Medium') . '</label> ' .
|
|
||||||
form::number('media_img_m_size', [
|
|
||||||
'min' => -1,
|
|
||||||
'max' => 999,
|
|
||||||
'default' => $blog_settings->system->media_img_m_size
|
|
||||||
]) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<h5>' . __('Default size of the inserted video (in pixels)') . '</h5>' .
|
|
||||||
'<p class="field"><label for="media_video_width">' . __('Width') . '</label> ' .
|
|
||||||
form::number('media_video_width', [
|
|
||||||
'min' => -1,
|
|
||||||
'max' => 999,
|
|
||||||
'default' => $blog_settings->system->media_video_width
|
|
||||||
]) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p class="field"><label for="media_video_height">' . __('Height') . '</label> ' .
|
|
||||||
form::number('media_video_height', [
|
|
||||||
'min' => -1,
|
|
||||||
'max' => 999,
|
|
||||||
'default' => $blog_settings->system->media_video_height
|
|
||||||
]) .
|
|
||||||
'</p>' .
|
|
||||||
'</div>' .
|
|
||||||
|
|
||||||
'<div class="col">' .
|
|
||||||
'<h5>' . __('Default image insertion attributes') . '</h5>' .
|
|
||||||
'<p class="vertical-separator"><label for="media_img_title_pattern">' . __('Inserted image title') . '</label>' .
|
|
||||||
form::combo('media_img_title_pattern', $img_title_combo, html::escapeHTML($blog_settings->system->media_img_title_pattern)) . '</p>' .
|
|
||||||
'<p><label for="media_img_use_dto_first" class="classic">' .
|
|
||||||
form::checkbox('media_img_use_dto_first', '1', $blog_settings->system->media_img_use_dto_first) .
|
|
||||||
__('Use original media date if possible') . '</label></p>' .
|
|
||||||
'<p><label for="media_img_no_date_alone" class="classic">' .
|
|
||||||
form::checkbox('media_img_no_date_alone', '1', $blog_settings->system->media_img_no_date_alone) .
|
|
||||||
__('Do not display date if alone in title') . '</label></p>' .
|
|
||||||
'<p class="form-note info">' . __('It is retrieved from the picture\'s metadata.') . '</p>' .
|
|
||||||
|
|
||||||
'<p class="field vertical-separator"><label for="media_img_default_size">' . __('Size of inserted image:') . '</label>' .
|
|
||||||
form::combo('media_img_default_size', $img_default_size_combo,
|
|
||||||
(html::escapeHTML($blog_settings->system->media_img_default_size) != '' ? html::escapeHTML($blog_settings->system->media_img_default_size) : 'm')) .
|
|
||||||
'</p>' .
|
|
||||||
'<p class="field"><label for="media_img_default_alignment">' . __('Image alignment:') . '</label>' .
|
|
||||||
form::combo('media_img_default_alignment', $img_default_alignment_combo, html::escapeHTML($blog_settings->system->media_img_default_alignment)) .
|
|
||||||
'</p>' .
|
|
||||||
'<p><label for="media_img_default_link">' .
|
|
||||||
form::checkbox('media_img_default_link', '1', $blog_settings->system->media_img_default_link) .
|
|
||||||
__('Insert a link to the original image') . '</label></p>' .
|
|
||||||
'<p class="field"><label for="media_img_default_legend">' . __('Image legend and title:') . '</label>' .
|
|
||||||
form::combo('media_img_default_legend', $img_default_legend_combo, html::escapeHTML($blog_settings->system->media_img_default_legend)) .
|
|
||||||
'</p>' .
|
|
||||||
'</div>' .
|
|
||||||
'</div>' .
|
|
||||||
'<br class="clear" />' . //Opera sucks
|
|
||||||
|
|
||||||
'</div>' .
|
|
||||||
'</div>';
|
|
||||||
|
|
||||||
echo '<div id="advanced-pref"><h3>' . __('Advanced parameters') . '</h3>';
|
|
||||||
|
|
||||||
if ($core->auth->isSuperAdmin()) {
|
|
||||||
echo '<div class="fieldset"><h4>' . __('Blog details') . '</h4>';
|
|
||||||
echo
|
|
||||||
'<p><label for="blog_id" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Blog ID:') . '</label>' .
|
|
||||||
form::field('blog_id', 30, 32, html::escapeHTML($blog_id), '', '', false, 'required placeholder="' . __('Blog ID') . '"') . '</p>' .
|
|
||||||
'<p class="form-note">' . __('At least 2 characters using letters, numbers or symbols.') . '</p> ' .
|
|
||||||
'<p class="form-note warn">' . __('Please note that changing your blog ID may require changes in your public index.php file.') . '</p>';
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<p><label for="blog_url" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Blog URL:') . '</label>' .
|
|
||||||
form::url('blog_url', [
|
|
||||||
'size' => 50,
|
|
||||||
'max' => 255,
|
|
||||||
'default' => html::escapeHTML($blog_url),
|
|
||||||
'extra_html' => 'required placeholder="' . __('Blog URL') . '"'
|
|
||||||
]) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="url_scan">' . __('URL scan method:') . '</label>' .
|
|
||||||
form::combo('url_scan', $url_scan_combo, $blog_settings->system->url_scan) . '</p>';
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
# Test URL of blog by testing it's ATOM feed
|
|
||||||
$file = $blog_url . $core->url->getURLFor('feed', 'atom');
|
|
||||||
$path = '';
|
|
||||||
$status = '404';
|
|
||||||
$content = '';
|
|
||||||
|
|
||||||
$client = netHttp::initClient($file, $path);
|
|
||||||
if ($client !== false) {
|
|
||||||
$client->setTimeout(4);
|
|
||||||
$client->setUserAgent($_SERVER['HTTP_USER_AGENT']);
|
|
||||||
$client->get($path);
|
|
||||||
$status = $client->getStatus();
|
|
||||||
$content = $client->getContent();
|
|
||||||
}
|
|
||||||
if ($status != '200') {
|
|
||||||
// Might be 404 (URL not found), 670 (blog not online), ...
|
|
||||||
echo
|
|
||||||
'<p class="form-note warn">' .
|
|
||||||
sprintf(__('The URL of blog or the URL scan method might not be well set (<code>%s</code> return a <strong>%s</strong> status).'),
|
|
||||||
html::escapeHTML($file), $status) .
|
|
||||||
'</p>';
|
|
||||||
} else {
|
|
||||||
if (substr($content, 0, 6) != '<?xml ') {
|
|
||||||
// Not well formed XML feed
|
|
||||||
echo
|
|
||||||
'<p class="form-note warn">' .
|
|
||||||
sprintf(__('The URL of blog or the URL scan method might not be well set (<code>%s</code> does not return an ATOM feed).'),
|
|
||||||
html::escapeHTML($file)) .
|
|
||||||
'</p>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
echo '</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<div class="fieldset"><h4>' . __('Blog configuration') . '</h4>' .
|
|
||||||
|
|
||||||
'<p><label for="post_url_format">' . __('New post URL format:') . '</label>' .
|
|
||||||
form::combo('post_url_format', $post_url_combo, html::escapeHTML($blog_settings->system->post_url_format)) .
|
|
||||||
'</p>' .
|
|
||||||
'<p class="chosen form-note">' . __('Sample:') . ' ' . $core->blog->getPostURL('', date('Y-m-d H:i:00', $now), __('Dotclear'), 42) . '</p>' .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="note_title_tag">' . __('HTML tag for the title of the notes on the blog:') . '</label>' .
|
|
||||||
form::combo('note_title_tag', $note_title_tag_combo, $blog_settings->system->note_title_tag) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="enable_xmlrpc" class="classic">' .
|
|
||||||
form::checkbox('enable_xmlrpc', '1', $blog_settings->system->enable_xmlrpc) .
|
|
||||||
__('Enable XML/RPC interface') . '</label>' . '</p>' .
|
|
||||||
'<p class="form-note info">' . __('XML/RPC interface allows you to edit your blog with an external client.') . '</p>';
|
|
||||||
|
|
||||||
if ($blog_settings->system->enable_xmlrpc) {
|
|
||||||
echo
|
|
||||||
'<p>' . __('XML/RPC interface is active. You should set the following parameters on your XML/RPC client:') . '</p>' .
|
|
||||||
'<ul>' .
|
|
||||||
'<li>' . __('Server URL:') . ' <strong><code>' .
|
|
||||||
sprintf(DC_XMLRPC_URL, $core->blog->url, $core->blog->id) .
|
|
||||||
'</code></strong></li>' .
|
|
||||||
'<li>' . __('Blogging system:') . ' <strong><code>Movable Type</code></strong></li>' .
|
|
||||||
'<li>' . __('User name:') . ' <strong><code>' . $core->auth->userID() . '</code></strong></li>' .
|
|
||||||
'<li>' . __('Password:') . ' <strong><code><' . __('your password') . '></code></strong></li>' .
|
|
||||||
'<li>' . __('Blog ID:') . ' <strong><code>1</code></strong></li>' .
|
|
||||||
'</ul>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo
|
|
||||||
'</div>';
|
|
||||||
|
|
||||||
// Search engines policies
|
|
||||||
echo '<div class="fieldset"><h4>' . __('Search engines robots policy') . '</h4>';
|
|
||||||
|
|
||||||
$i = 0;
|
|
||||||
foreach ($robots_policy_options as $k => $v) {
|
|
||||||
echo '<p><label for="robots_policy-' . $i . '" class="classic">' .
|
|
||||||
form::radio(['robots_policy', 'robots_policy-' . $i], $k, $blog_settings->system->robots_policy == $k) . ' ' . $v . '</label></p>';
|
|
||||||
$i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '</div>';
|
|
||||||
|
|
||||||
echo '<div class="fieldset"><h4>' . __('jQuery javascript library') . '</h4>' .
|
|
||||||
|
|
||||||
'<p><label for="jquery_needed" class="classic">' .
|
|
||||||
form::checkbox('jquery_needed', '1', $blog_settings->system->jquery_needed) .
|
|
||||||
__('Load the jQuery library') . '</label></p>' .
|
|
||||||
|
|
||||||
'<p><label for="jquery_version" class="classic">' . __('jQuery version to be loaded for this blog:') . '</label>' . ' ' .
|
|
||||||
form::combo('jquery_version', $jquery_versions_combo, $blog_settings->system->jquery_version) .
|
|
||||||
'</p>' .
|
|
||||||
'<br class="clear" />' . //Opera sucks
|
|
||||||
|
|
||||||
'</div>';
|
|
||||||
|
|
||||||
echo '<div class="fieldset"><h4>' . __('Blog security') . '</h4>' .
|
|
||||||
|
|
||||||
'<p><label for="prevents_clickjacking" class="classic">' .
|
|
||||||
form::checkbox('prevents_clickjacking', '1', $blog_settings->system->prevents_clickjacking) .
|
|
||||||
__('Protect the blog from Clickjacking (see <a href="https://en.wikipedia.org/wiki/Clickjacking">Wikipedia</a>)') . '</label></p>' .
|
|
||||||
'<br class="clear" />' . //Opera sucks
|
|
||||||
|
|
||||||
'</div>';
|
|
||||||
|
|
||||||
echo '</div>'; // End advanced
|
|
||||||
|
|
||||||
echo '<div id="plugins-pref"><h3>' . __('Plugins parameters') . '</h3>';
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminBlogPreferencesForm
|
|
||||||
$core->callBehavior('adminBlogPreferencesForm', $core, $blog_settings);
|
|
||||||
|
|
||||||
echo '</div>'; // End 3rd party, aka plugins
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<p><input type="submit" accesskey="s" value="' . __('Save') . '" />' .
|
|
||||||
(!$standalone ? form::hidden('id', $blog_id) : '') .
|
|
||||||
'</p>' .
|
|
||||||
'</form>';
|
|
||||||
|
|
||||||
if ($core->auth->isSuperAdmin() && $blog_id != $core->blog->id) {
|
|
||||||
echo
|
|
||||||
'<form action="' . $core->adminurl->get("admin.blog.del") . '" method="post">' .
|
|
||||||
'<p><input type="submit" class="delete" value="' . __('Delete this blog') . '" />' .
|
|
||||||
form::hidden(['blog_id'], $blog_id) .
|
|
||||||
$core->formNonce() . '</p>' .
|
|
||||||
'</form>';
|
|
||||||
} else {
|
|
||||||
if ($blog_id == $core->blog->id) {
|
|
||||||
echo '<p class="message">' . __('The current blog cannot be deleted.') . '</p>';
|
|
||||||
} else {
|
|
||||||
echo '<p class="message">' . __('Only superadmin can delete a blog.') . '</p>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '</div>';
|
|
||||||
|
|
||||||
#
|
|
||||||
# Users on the blog (with permissions)
|
|
||||||
|
|
||||||
$blog_users = $core->getBlogPermissions($blog_id, $core->auth->isSuperAdmin());
|
|
||||||
$perm_types = $core->auth->getPermissionsTypes();
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<div class="multi-part" id="users" title="' . __('Users') . '">' .
|
|
||||||
'<h3 class="out-of-screen-if-js">' . __('Users on this blog') . '</h3>';
|
|
||||||
|
|
||||||
if (empty($blog_users)) {
|
|
||||||
echo '<p>' . __('No users') . '</p>';
|
|
||||||
} else {
|
|
||||||
if ($core->auth->isSuperAdmin()) {
|
|
||||||
$user_url_p = '<a href="' . $core->adminurl->get("admin.user", ['id' => '%1$s'], '&', true) . '">%1$s</a>';
|
|
||||||
} else {
|
|
||||||
$user_url_p = '%1$s';
|
|
||||||
}
|
|
||||||
|
|
||||||
# Sort users list on user_id key
|
|
||||||
dcUtils::lexicalKeySort($blog_users);
|
|
||||||
|
|
||||||
$post_type = $core->getPostTypes();
|
|
||||||
$current_blog_id = $core->blog->id;
|
|
||||||
if ($blog_id != $core->blog->id) {
|
|
||||||
$core->setBlog($blog_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '<div>';
|
|
||||||
foreach ($blog_users as $k => $v) {
|
|
||||||
if (count($v['p']) > 0) {
|
|
||||||
echo
|
|
||||||
'<div class="user-perm' . ($v['super'] ? ' user_super' : '') . '">' .
|
|
||||||
'<h4>' . sprintf($user_url_p, html::escapeHTML($k)) .
|
|
||||||
' (' . html::escapeHTML(dcUtils::getUserCN(
|
|
||||||
$k, $v['name'], $v['firstname'], $v['displayname']
|
|
||||||
)) . ')</h4>';
|
|
||||||
|
|
||||||
if ($core->auth->isSuperAdmin()) {
|
|
||||||
echo
|
|
||||||
'<p>' . __('Email:') . ' ' .
|
|
||||||
($v['email'] != '' ? '<a href="mailto:' . $v['email'] . '">' . $v['email'] . '</a>' : __('(none)')) .
|
|
||||||
'</p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<h5>' . __('Publications on this blog:') . '</h5>' .
|
|
||||||
'<ul>';
|
|
||||||
foreach ($post_type as $type => $pt_info) {
|
|
||||||
$params = [
|
|
||||||
'post_type' => $type,
|
|
||||||
'user_id' => $k
|
|
||||||
];
|
|
||||||
echo '<li>' . sprintf(__('%1$s: %2$s'), __($pt_info['label']), $core->blog->getPosts($params, true)->f(0)) . '</li>';
|
|
||||||
}
|
|
||||||
echo
|
|
||||||
'</ul>';
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<h5>' . __('Permissions:') . '</h5>' .
|
|
||||||
'<ul>';
|
|
||||||
if ($v['super']) {
|
|
||||||
echo '<li class="user_super">' . __('Super administrator') . '<br />' .
|
|
||||||
'<span class="form-note">' . __('All rights on all blogs.') . '</span></li>';
|
|
||||||
} else {
|
|
||||||
foreach ($v['p'] as $p => $V) {
|
|
||||||
if (isset($perm_types[$p])) {
|
|
||||||
echo '<li ' . ($p == 'admin' ? 'class="user_admin"' : '') . '>' . __($perm_types[$p]);
|
|
||||||
} else {
|
|
||||||
echo '<li>' . sprintf(__('[%s] (unreferenced permission)'), $p);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($p == 'admin') {
|
|
||||||
echo '<br /><span class="form-note">' . __('All rights on this blog.') . '</span>';
|
|
||||||
}
|
|
||||||
echo '</li>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo
|
|
||||||
'</ul>';
|
|
||||||
|
|
||||||
if (!$v['super'] && $core->auth->isSuperAdmin()) {
|
|
||||||
echo
|
|
||||||
'<form action="' . $core->adminurl->get('admin.user.actions') . '" method="post">' .
|
|
||||||
'<p class="change-user-perm"><input type="submit" class="reset" value="' . __('Change permissions') . '" />' .
|
|
||||||
form::hidden(['redir'], $core->adminurl->get("admin.blog.pref", ['id' => $k], '&')) .
|
|
||||||
form::hidden(['action'], 'perms') .
|
|
||||||
form::hidden(['users[]'], $k) .
|
|
||||||
form::hidden(['blogs[]'], $blog_id) .
|
|
||||||
$core->formNonce() .
|
|
||||||
'</p>' .
|
|
||||||
'</form>';
|
|
||||||
}
|
|
||||||
echo '</div>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo '</div>';
|
|
||||||
if ($current_blog_id != $core->blog->id) {
|
|
||||||
$core->setBlog($current_blog_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
dcPage::helpBlock('core_blog_pref');
|
|
||||||
dcPage::close();
|
|
||||||
@ -1,250 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Backend
|
|
||||||
*
|
|
||||||
* @copyright Olivier Meunier & Association Dotclear
|
|
||||||
* @copyright GPL-2.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
|
||||||
|
|
||||||
dcPage::check('admin');
|
|
||||||
|
|
||||||
# -- Loading themes --
|
|
||||||
$core->themes = new dcThemes($core);
|
|
||||||
$core->themes->loadModules($core->blog->themes_path, null);
|
|
||||||
|
|
||||||
# -- Page helper --
|
|
||||||
$list = new adminThemesList(
|
|
||||||
$core->themes,
|
|
||||||
$core->blog->themes_path,
|
|
||||||
$core->blog->settings->system->store_theme_url,
|
|
||||||
!empty($_GET['nocache'])
|
|
||||||
);
|
|
||||||
adminThemesList::$distributed_modules = explode(',', DC_DISTRIB_THEMES);
|
|
||||||
|
|
||||||
# -- Theme screenshot --
|
|
||||||
if (!empty($_GET['shot']) && $list->modules->moduleExists($_GET['shot'])) {
|
|
||||||
|
|
||||||
$f = path::real(empty($_GET['src']) ?
|
|
||||||
$core->blog->themes_path . '/' . $_GET['shot'] . '/screenshot.jpg' :
|
|
||||||
$core->blog->themes_path . '/' . $_GET['shot'] . '/' . path::clean($_GET['src'])
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!file_exists($f)) {
|
|
||||||
$f = dirname(__FILE__) . '/images/noscreenshot.png';
|
|
||||||
}
|
|
||||||
|
|
||||||
http::cache(array_merge([$f], get_included_files()));
|
|
||||||
|
|
||||||
header('Content-Type: ' . files::getMimeType($f));
|
|
||||||
header('Content-Length: ' . filesize($f));
|
|
||||||
readfile($f);
|
|
||||||
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
# -- Display module configuration page --
|
|
||||||
if ($list->setConfiguration($core->blog->settings->system->theme)) {
|
|
||||||
|
|
||||||
# Get content before page headers
|
|
||||||
include $list->includeConfiguration();
|
|
||||||
|
|
||||||
# Gather content
|
|
||||||
$list->getConfiguration();
|
|
||||||
|
|
||||||
# Display page
|
|
||||||
dcPage::open(__('Blog appearance'),
|
|
||||||
dcPage::jsPageTabs() .
|
|
||||||
|
|
||||||
# --BEHAVIOR-- themesToolsHeaders
|
|
||||||
$core->callBehavior('themesToolsHeaders', $core, true),
|
|
||||||
|
|
||||||
dcPage::breadcrumb(
|
|
||||||
[
|
|
||||||
html::escapeHTML($core->blog->name) => '',
|
|
||||||
__('Blog appearance') => $list->getURL('', false),
|
|
||||||
'<span class="page-title">' . __('Theme configuration') . '</span>' => ''
|
|
||||||
])
|
|
||||||
);
|
|
||||||
|
|
||||||
# Display previously gathered content
|
|
||||||
$list->displayConfiguration();
|
|
||||||
|
|
||||||
dcPage::helpBlock('core_blog_theme_conf');
|
|
||||||
dcPage::close();
|
|
||||||
|
|
||||||
# Stop reading code here
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
# -- Execute actions --
|
|
||||||
try {
|
|
||||||
$list->doActions();
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
# -- Page header --
|
|
||||||
dcPage::open(__('Themes management'),
|
|
||||||
dcPage::jsLoad('js/_blog_theme.js') .
|
|
||||||
dcPage::jsPageTabs() .
|
|
||||||
|
|
||||||
# --BEHAVIOR-- themesToolsHeaders
|
|
||||||
$core->callBehavior('themesToolsHeaders', $core, false),
|
|
||||||
|
|
||||||
dcPage::breadcrumb(
|
|
||||||
[
|
|
||||||
html::escapeHTML($core->blog->name) => '',
|
|
||||||
'<span class="page-title">' . __('Blog appearance') . '</span>' => ''
|
|
||||||
])
|
|
||||||
);
|
|
||||||
|
|
||||||
# -- Display modules lists --
|
|
||||||
if ($core->auth->isSuperAdmin()) {
|
|
||||||
|
|
||||||
if (!$core->error->flag()) {
|
|
||||||
if (!empty($_GET['nocache'])) {
|
|
||||||
dcPage::success(__('Manual checking of themes update done successfully.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Updated modules from repo
|
|
||||||
$modules = $list->store->get(true);
|
|
||||||
if (!empty($modules)) {
|
|
||||||
echo
|
|
||||||
'<div class="multi-part" id="update" title="' . html::escapeHTML(__('Update themes')) . '">' .
|
|
||||||
'<h3>' . html::escapeHTML(__('Update themes')) . '</h3>' .
|
|
||||||
'<p>' . sprintf(
|
|
||||||
__('There is one theme to update available from repository.', 'There are %s themes to update available from repository.', count($modules)),
|
|
||||||
count($modules)
|
|
||||||
) . '</p>';
|
|
||||||
|
|
||||||
$list
|
|
||||||
->setList('theme-update')
|
|
||||||
->setTab('themes')
|
|
||||||
->setModules($modules)
|
|
||||||
->displayModules(
|
|
||||||
/*cols */['checkbox', 'name', 'sshot', 'desc', 'author', 'version', 'current_version', 'parent'],
|
|
||||||
/* actions */['update', 'delete']
|
|
||||||
);
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<p class="info vertical-separator">' . sprintf(
|
|
||||||
__("Visit %s repository, the resources center for Dotclear."),
|
|
||||||
'<a href="https://themes.dotaddict.org/galerie-dc2/">Dotaddict</a>'
|
|
||||||
) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'</div>';
|
|
||||||
} else {
|
|
||||||
echo
|
|
||||||
'<form action="' . $list->getURL('', false) . '" method="get">' .
|
|
||||||
'<p><input type="hidden" name="nocache" value="1" />' .
|
|
||||||
'<input type="submit" value="' . __('Force checking update of themes') . '" /></p>' .
|
|
||||||
'</form>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Activated modules
|
|
||||||
$modules = $list->modules->getModules();
|
|
||||||
if (!empty($modules)) {
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<div class="multi-part" id="themes" title="' . __('Installed themes') . '">' .
|
|
||||||
'<h3>' . __('Installed themes') . '</h3>' .
|
|
||||||
'<p class="more-info">' . __('You can configure and manage installed themes from this list.') . '</p>';
|
|
||||||
|
|
||||||
$list
|
|
||||||
->setList('theme-activate')
|
|
||||||
->setTab('themes')
|
|
||||||
->setModules($modules)
|
|
||||||
->displayModules(
|
|
||||||
/* cols */['sshot', 'distrib', 'name', 'config', 'desc', 'author', 'version', 'parent'],
|
|
||||||
/* actions */['select', 'behavior', 'deactivate', 'delete']
|
|
||||||
);
|
|
||||||
|
|
||||||
echo
|
|
||||||
'</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
# Deactivated modules
|
|
||||||
$modules = $list->modules->getDisabledModules();
|
|
||||||
if (!empty($modules)) {
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<div class="multi-part" id="deactivate" title="' . __('Deactivated themes') . '">' .
|
|
||||||
'<h3>' . __('Deactivated themes') . '</h3>' .
|
|
||||||
'<p class="more-info">' . __('Deactivated themes are installed but not usable. You can activate them from here.') . '</p>';
|
|
||||||
|
|
||||||
$list
|
|
||||||
->setList('theme-deactivate')
|
|
||||||
->setTab('themes')
|
|
||||||
->setModules($modules)
|
|
||||||
->displayModules(
|
|
||||||
/* cols */['name', 'distrib'],
|
|
||||||
/* actions */['activate', 'delete']
|
|
||||||
);
|
|
||||||
|
|
||||||
echo
|
|
||||||
'</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($core->auth->isSuperAdmin() && $list->isWritablePath()) {
|
|
||||||
|
|
||||||
# New modules from repo
|
|
||||||
$search = $list->getSearch();
|
|
||||||
$modules = $search ? $list->store->search($search) : $list->store->get();
|
|
||||||
|
|
||||||
if (!empty($search) || !empty($modules)) {
|
|
||||||
echo
|
|
||||||
'<div class="multi-part" id="new" title="' . __('Add themes') . '">' .
|
|
||||||
'<h3>' . __('Add themes from repository') . '</h3>';
|
|
||||||
// '<p>'.__('Search and install themes directly from repository.').'</p>';
|
|
||||||
|
|
||||||
$list
|
|
||||||
->setList('theme-new')
|
|
||||||
->setTab('new')
|
|
||||||
->setModules($modules)
|
|
||||||
->displaySearch()
|
|
||||||
->displayIndex()
|
|
||||||
->displayModules(
|
|
||||||
/* cols */['expander', 'sshot', 'name', 'score', 'config', 'desc', 'author', 'version', 'parent', 'details', 'support'],
|
|
||||||
/* actions */['install'],
|
|
||||||
/* nav limit */true
|
|
||||||
);
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<p class="info vertical-separator">' . sprintf(
|
|
||||||
__("Visit %s repository, the resources center for Dotclear."),
|
|
||||||
'<a href="https://themes.dotaddict.org/galerie-dc2/">Dotaddict</a>'
|
|
||||||
) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
# Add a new plugin
|
|
||||||
echo
|
|
||||||
'<div class="multi-part" id="addtheme" title="' . __('Install or upgrade manually') . '">' .
|
|
||||||
'<h3>' . __('Add themes from a package') . '</h3>' .
|
|
||||||
'<p class="more-info">' . __('You can install themes by uploading or downloading zip files.') . '</p>';
|
|
||||||
|
|
||||||
$list->displayManualForm();
|
|
||||||
|
|
||||||
echo
|
|
||||||
'</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
# --BEHAVIOR-- themesToolsTabs
|
|
||||||
$core->callBehavior('themesToolsTabs', $core);
|
|
||||||
|
|
||||||
# -- Notice for super admin --
|
|
||||||
if ($core->auth->isSuperAdmin() && !$list->isWritablePath()) {
|
|
||||||
echo
|
|
||||||
'<p class="warning">' . __('Some functions are disabled, please give write access to your themes directory to enable them.') . '</p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
dcPage::helpBlock('core_blog_theme');
|
|
||||||
dcPage::close();
|
|
||||||
@ -1,185 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Backend
|
|
||||||
*
|
|
||||||
* @copyright Olivier Meunier & Association Dotclear
|
|
||||||
* @copyright GPL-2.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
|
||||||
|
|
||||||
dcPage::check('usage,contentadmin');
|
|
||||||
|
|
||||||
# Filters
|
|
||||||
$status_combo = array_merge(
|
|
||||||
['-' => ''],
|
|
||||||
dcAdminCombos::getBlogStatusesCombo()
|
|
||||||
);
|
|
||||||
|
|
||||||
$sortby_combo = [
|
|
||||||
__('Last update') => 'blog_upddt',
|
|
||||||
__('Blog name') => 'UPPER(blog_name)',
|
|
||||||
__('Blog ID') => 'B.blog_id',
|
|
||||||
__('Status') => 'blog_status'
|
|
||||||
];
|
|
||||||
|
|
||||||
$order_combo = [
|
|
||||||
__('Descending') => 'desc',
|
|
||||||
__('Ascending') => 'asc'
|
|
||||||
];
|
|
||||||
|
|
||||||
# Actions
|
|
||||||
|
|
||||||
if ($core->auth->isSuperAdmin()) {
|
|
||||||
$blogs_actions_page = new dcBlogsActionsPage($core, $core->adminurl->get("admin.blogs"));
|
|
||||||
if ($blogs_actions_page->process()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Requests
|
|
||||||
$q = !empty($_GET['q']) ? $_GET['q'] : '';
|
|
||||||
$status = isset($_GET['status']) ? $_GET['status'] : '';
|
|
||||||
$sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'blog_upddt';
|
|
||||||
$order = !empty($_GET['order']) ? $_GET['order'] : 'desc';
|
|
||||||
|
|
||||||
$show_filters = false;
|
|
||||||
|
|
||||||
$page = !empty($_GET['page']) ? max(1, (integer) $_GET['page']) : 1;
|
|
||||||
$nb_per_page = 30;
|
|
||||||
|
|
||||||
if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) {
|
|
||||||
if ($nb_per_page != (integer) $_GET['nb']) {
|
|
||||||
$show_filters = true;
|
|
||||||
}
|
|
||||||
$nb_per_page = (integer) $_GET['nb'];
|
|
||||||
}
|
|
||||||
|
|
||||||
# - Search filter
|
|
||||||
if ($q) {
|
|
||||||
$params['q'] = $q;
|
|
||||||
$show_filters = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
# - Status filter
|
|
||||||
if ($status !== '' && in_array($status, $status_combo, true)) {
|
|
||||||
$params['blog_status'] = $status;
|
|
||||||
$show_filters = true;
|
|
||||||
} else {
|
|
||||||
$status = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
# - Sortby and order filter
|
|
||||||
if ($sortby !== '' && in_array($sortby, $sortby_combo, true)) {
|
|
||||||
if ($order !== '' && in_array($order, $order_combo, true)) {
|
|
||||||
$params['order'] = $sortby . ' ' . $order;
|
|
||||||
} else {
|
|
||||||
$order = 'desc';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$sortby = 'blog_upddt';
|
|
||||||
$order = 'desc';
|
|
||||||
}
|
|
||||||
if ($sortby != 'blog_upddt' || $order != 'desc') {
|
|
||||||
$show_filters = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$params['limit'] = [(($page - 1) * $nb_per_page), $nb_per_page];
|
|
||||||
|
|
||||||
try {
|
|
||||||
$counter = $core->getBlogs($params, 1);
|
|
||||||
$rs = $core->getBlogs($params);
|
|
||||||
$nb_blog = $counter->f(0);
|
|
||||||
$rsStatic = $rs->toStatic();
|
|
||||||
if (($sortby != 'blog_upddt') && ($sortby != 'blog_status')) {
|
|
||||||
// Sort blog list using lexical order if necessary
|
|
||||||
$rsStatic->extend('rsExtUser');
|
|
||||||
$rsStatic = $rsStatic->toExtStatic();
|
|
||||||
$rsStatic->lexicalSort(($sortby == 'UPPER(blog_name)' ? 'blog_name' : 'blog_id'), $order);
|
|
||||||
}
|
|
||||||
$blog_list = new adminBlogList($core, $rs, $counter->f(0));
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* DISPLAY
|
|
||||||
-------------------------------------------------------- */
|
|
||||||
|
|
||||||
dcPage::open(__('List of blogs'),
|
|
||||||
dcPage::jsLoad('js/_blogs.js') . dcPage::jsFilterControl($show_filters),
|
|
||||||
dcPage::breadcrumb(
|
|
||||||
[
|
|
||||||
__('System') => '',
|
|
||||||
__('List of blogs') => ''
|
|
||||||
])
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!$core->error->flag()) {
|
|
||||||
if ($core->auth->isSuperAdmin()) {
|
|
||||||
echo '<p class="top-add"><a class="button add" href="' . $core->adminurl->get("admin.blog") . '">' . __('Create a new blog') . '</a></p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<form action="' . $core->adminurl->get("admin.blogs") . '" method="get" id="filters-form">' .
|
|
||||||
'<h3 class="out-of-screen-if-js">' . __('Show filters and display options') . '</h3>' .
|
|
||||||
|
|
||||||
'<div class="table">' .
|
|
||||||
'<div class="cell">' .
|
|
||||||
'<h4>' . __('Filters') . '</h4>' .
|
|
||||||
'<p><label for="q" class="ib">' . __('Search:') . '</label> ' .
|
|
||||||
form::field('q', 20, 255, html::escapeHTML($q)) . '</p>' .
|
|
||||||
($core->auth->isSuperAdmin() ?
|
|
||||||
'<p><label for="status" class="ib">' . __('Status:') . '</label> ' .
|
|
||||||
form::combo('status', $status_combo, $status) . '</p>' : '') .
|
|
||||||
'</div>' .
|
|
||||||
|
|
||||||
'<div class="cell filters-options">' .
|
|
||||||
'<h4>' . __('Display options') . '</h4>' .
|
|
||||||
'<p><label for="sortby" class="ib">' . __('Order by:') . '</label> ' .
|
|
||||||
form::combo('sortby', $sortby_combo, html::escapeHTML($sortby)) . '</p>' .
|
|
||||||
'<p><label for="order" class="ib">' . __('Sort:') . '</label> ' .
|
|
||||||
form::combo('order', $order_combo, html::escapeHTML($order)) . '</p>' .
|
|
||||||
'<p><span class="label ib">' . __('Show') . '</span> <label for="nb" class="classic">' .
|
|
||||||
form::number('nb', 0, 999, $nb_per_page) . ' ' . __('blogs per page') . '</label></p>' .
|
|
||||||
'</div>' .
|
|
||||||
'</div>' .
|
|
||||||
|
|
||||||
'<p><input type="submit" value="' . __('Apply filters and display options') . '" />' .
|
|
||||||
'<br class="clear" /></p>' . //Opera sucks
|
|
||||||
'</form>';
|
|
||||||
|
|
||||||
# Show blogs
|
|
||||||
$blog_list->display($page, $nb_per_page,
|
|
||||||
($core->auth->isSuperAdmin() ?
|
|
||||||
'<form action="' . $core->adminurl->get("admin.blogs") . '" method="post" id="form-blogs">' : '') .
|
|
||||||
|
|
||||||
'%s' .
|
|
||||||
|
|
||||||
($core->auth->isSuperAdmin() ?
|
|
||||||
'<div class="two-cols clearfix">' .
|
|
||||||
'<p class="col checkboxes-helpers"></p>' .
|
|
||||||
|
|
||||||
'<p class="col right"><label for="action" class="classic">' . __('Selected blogs action:') . '</label> ' .
|
|
||||||
form::combo('action', $blogs_actions_page->getCombo(),
|
|
||||||
['class' => 'online', 'extra_html' => 'title="' . __('Actions') . '"']) .
|
|
||||||
$core->formNonce() .
|
|
||||||
'<input id="do-action" type="submit" value="' . __('ok') . '" /></p>' .
|
|
||||||
'</div>' .
|
|
||||||
|
|
||||||
'<p><label for="pwd" class="classic">' . __('Please give your password to confirm blog(s) deletion:') . '</label> ' .
|
|
||||||
form::password('pwd', 20, 255, ['autocomplete' => 'current-password']) . '</p>' .
|
|
||||||
|
|
||||||
form::hidden(['sortby'], $sortby) .
|
|
||||||
form::hidden(['order'], $order) .
|
|
||||||
form::hidden(['status'], $status) .
|
|
||||||
form::hidden(['page'], $page) .
|
|
||||||
form::hidden(['nb'], $nb_per_page) .
|
|
||||||
|
|
||||||
'</form>' : ''),
|
|
||||||
$show_filters
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
dcPage::helpBlock('core_blogs');
|
|
||||||
dcPage::close();
|
|
||||||
@ -1,219 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Backend
|
|
||||||
*
|
|
||||||
* @copyright Olivier Meunier & Association Dotclear
|
|
||||||
* @copyright GPL-2.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
|
||||||
|
|
||||||
dcPage::check('categories');
|
|
||||||
|
|
||||||
# Remove a categories
|
|
||||||
if (!empty($_POST['delete'])) {
|
|
||||||
$keys = array_keys($_POST['delete']);
|
|
||||||
$cat_id = (int) $keys[0];
|
|
||||||
|
|
||||||
# Check if category to delete exists
|
|
||||||
$c = $core->blog->getCategory((integer) $cat_id);
|
|
||||||
if ($c->isEmpty()) {
|
|
||||||
dcPage::addErrorNotice(__('This category does not exist.'));
|
|
||||||
$core->adminurl->redirect("admin.categories");
|
|
||||||
}
|
|
||||||
$name = $c->cat_title;
|
|
||||||
unset($c);
|
|
||||||
|
|
||||||
try {
|
|
||||||
# Delete category
|
|
||||||
$core->blog->delCategory($cat_id);
|
|
||||||
dcPage::addSuccessNotice(sprintf(__('The category "%s" has been successfully deleted.'), html::escapeHTML($name)));
|
|
||||||
$core->adminurl->redirect("admin.categories");
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# move post into a category
|
|
||||||
if (!empty($_POST['mov']) && !empty($_POST['mov_cat'])) {
|
|
||||||
try {
|
|
||||||
# Check if category where to move posts exists
|
|
||||||
$keys = array_keys($_POST['mov']);
|
|
||||||
$cat_id = (int) $keys[0];
|
|
||||||
$mov_cat = (int) $_POST['mov_cat'][$cat_id];
|
|
||||||
|
|
||||||
$mov_cat = $mov_cat ?: null;
|
|
||||||
if ($mov_cat !== null) {
|
|
||||||
$c = $core->blog->getCategory($mov_cat);
|
|
||||||
if ($c->isEmpty()) {
|
|
||||||
throw new Exception(__('Category where to move entries does not exist'));
|
|
||||||
}
|
|
||||||
$name = $c->cat_title;
|
|
||||||
unset($c);
|
|
||||||
}
|
|
||||||
# Move posts
|
|
||||||
if ($mov_cat != $cat_id) {
|
|
||||||
$core->blog->changePostsCategory($cat_id, $mov_cat);
|
|
||||||
}
|
|
||||||
dcPage::addSuccessNotice(sprintf(__('The entries have been successfully moved to category "%s"'),
|
|
||||||
html::escapeHTML($name)));
|
|
||||||
$core->adminurl->redirect("admin.categories");
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Update order
|
|
||||||
if (!empty($_POST['save_order']) && !empty($_POST['categories_order'])) {
|
|
||||||
$categories = json_decode($_POST['categories_order']);
|
|
||||||
|
|
||||||
foreach ($categories as $category) {
|
|
||||||
if (!empty($category->item_id) && !empty($category->left) && !empty($category->right)) {
|
|
||||||
$core->blog->updCategoryPosition($category->item_id, $category->left, $category->right);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dcPage::addSuccessNotice(__('Categories have been successfully reordered.'));
|
|
||||||
$core->adminurl->redirect("admin.categories");
|
|
||||||
}
|
|
||||||
|
|
||||||
# Reset order
|
|
||||||
if (!empty($_POST['reset'])) {
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$core->blog->resetCategoriesOrder();
|
|
||||||
dcPage::addSuccessNotice(__('Categories order has been successfully reset.'));
|
|
||||||
$core->adminurl->redirect("admin.categories");
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Display
|
|
||||||
-------------------------------------------------------- */
|
|
||||||
$rs = $core->blog->getCategories();
|
|
||||||
|
|
||||||
$starting_script = "";
|
|
||||||
|
|
||||||
$core->auth->user_prefs->addWorkspace('accessibility');
|
|
||||||
if (!$core->auth->user_prefs->accessibility->nodragdrop
|
|
||||||
&& $core->auth->check('categories', $core->blog->id)
|
|
||||||
&& $rs->count() > 1) {
|
|
||||||
$starting_script .= dcPage::jsLoad('js/jquery/jquery-ui.custom.js');
|
|
||||||
$starting_script .= dcPage::jsLoad('js/jquery/jquery.ui.touch-punch.js');
|
|
||||||
$starting_script .= dcPage::jsLoad('js/jquery/jquery.mjs.nestedSortable.js');
|
|
||||||
}
|
|
||||||
$starting_script .= dcPage::jsConfirmClose('form-categories');
|
|
||||||
$starting_script .= dcPage::jsLoad('js/_categories.js');
|
|
||||||
|
|
||||||
dcPage::open(__('Categories'), $starting_script,
|
|
||||||
dcPage::breadcrumb(
|
|
||||||
[
|
|
||||||
html::escapeHTML($core->blog->name) => '',
|
|
||||||
__('Categories') => ''
|
|
||||||
])
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!empty($_GET['del'])) {
|
|
||||||
dcPage::success(__('The category has been successfully removed.'));
|
|
||||||
}
|
|
||||||
if (!empty($_GET['reord'])) {
|
|
||||||
dcPage::success(__('Categories have been successfully reordered.'));
|
|
||||||
}
|
|
||||||
if (!empty($_GET['move'])) {
|
|
||||||
dcPage::success(__('Entries have been successfully moved to the category you choose.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$categories_combo = dcAdminCombos::getCategoriesCombo($rs);
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<p class="top-add"><a class="button add" href="' . $core->adminurl->get("admin.category") . '">' . __('New category') . '</a></p>';
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<div class="col">';
|
|
||||||
if ($rs->isEmpty()) {
|
|
||||||
echo '<p>' . __('No category so far.') . '</p>';
|
|
||||||
} else {
|
|
||||||
echo
|
|
||||||
'<form action="' . $core->adminurl->get("admin.categories") . '" method="post" id="form-categories">' .
|
|
||||||
'<div id="categories">';
|
|
||||||
|
|
||||||
$ref_level = $level = $rs->level - 1;
|
|
||||||
while ($rs->fetch()) {
|
|
||||||
$attr = 'id="cat_' . $rs->cat_id . '" class="cat-line clearfix"';
|
|
||||||
|
|
||||||
if ($rs->level > $level) {
|
|
||||||
echo str_repeat('<ul><li ' . $attr . '>', $rs->level - $level);
|
|
||||||
} elseif ($rs->level < $level) {
|
|
||||||
echo str_repeat('</li></ul>', -($rs->level - $level));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($rs->level <= $level) {
|
|
||||||
echo '</li><li ' . $attr . '>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<p class="cat-title"><label class="classic" for="cat_' . $rs->cat_id . '"><a href="' .
|
|
||||||
$core->adminurl->get("admin.category", ['id' => $rs->cat_id]) . '">' . html::escapeHTML($rs->cat_title) .
|
|
||||||
'</a></label> </p>' .
|
|
||||||
'<p class="cat-nb-posts">(<a href="' . $core->adminurl->get("admin.posts", ['cat_id' => $rs->cat_id]) . '">' .
|
|
||||||
sprintf(($rs->nb_post > 1 ? __('%d entries') : __('%d entry')), $rs->nb_post) . '</a>' .
|
|
||||||
', ' . __('total:') . ' ' . $rs->nb_total . ')</p>' .
|
|
||||||
'<p class="cat-url">' . __('URL:') . ' <code>' . html::escapeHTML($rs->cat_url) . '</code></p>';
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<p class="cat-buttons">';
|
|
||||||
if ($rs->nb_total > 0) {
|
|
||||||
// remove current category
|
|
||||||
echo
|
|
||||||
'<label for="mov_cat_' . $rs->cat_id . '">' . __('Move entries to') . '</label> ' .
|
|
||||||
form::combo(['mov_cat[' . $rs->cat_id . ']', 'mov_cat_' . $rs->cat_id], array_filter($categories_combo,
|
|
||||||
function ($cat) {return $cat->value != $GLOBALS['rs']->cat_id;}
|
|
||||||
), '', '') .
|
|
||||||
' <input type="submit" class="reset" name="mov[' . $rs->cat_id . ']" value="' . __('OK') . '"/>';
|
|
||||||
|
|
||||||
$attr_disabled = ' disabled="disabled"';
|
|
||||||
$input_class = 'disabled ';
|
|
||||||
} else {
|
|
||||||
$attr_disabled = '';
|
|
||||||
$input_class = '';
|
|
||||||
}
|
|
||||||
echo
|
|
||||||
' <input type="submit"' . $attr_disabled . ' class="' . $input_class . 'delete" name="delete[' . $rs->cat_id . ']" value="' . __('Delete category') . '"/>' .
|
|
||||||
'</p>';
|
|
||||||
|
|
||||||
$level = $rs->level;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($ref_level - $level < 0) {
|
|
||||||
echo str_repeat('</li></ul>', -($ref_level - $level));
|
|
||||||
}
|
|
||||||
echo
|
|
||||||
'</div>';
|
|
||||||
|
|
||||||
echo '<div class="clear">';
|
|
||||||
|
|
||||||
if ($core->auth->check('categories', $core->blog->id) && $rs->count() > 1) {
|
|
||||||
if (!$core->auth->user_prefs->accessibility->nodragdrop) {
|
|
||||||
echo '<p class="form-note hidden-if-no-js">' . __('To rearrange categories order, move items by drag and drop, then click on “Save categories order” button.') . '</p>';
|
|
||||||
}
|
|
||||||
echo
|
|
||||||
'<p><span class="hidden-if-no-js">' .
|
|
||||||
'<input type="hidden" id="categories_order" name="categories_order" value=""/>' .
|
|
||||||
'<input type="submit" name="save_order" id="save-set-order" value="' . __('Save categories order') . '" />' .
|
|
||||||
'</span> ';
|
|
||||||
} else {
|
|
||||||
echo '<p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<input type="submit" class="reset" name="reset" value="' . __('Reorder all categories on the top level') . '" />' .
|
|
||||||
$core->formNonce() . '</p>' .
|
|
||||||
'</div></form>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '</div>';
|
|
||||||
|
|
||||||
dcPage::helpBlock('core_categories');
|
|
||||||
dcPage::close();
|
|
||||||
@ -1,263 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Backend
|
|
||||||
*
|
|
||||||
* @copyright Olivier Meunier & Association Dotclear
|
|
||||||
* @copyright GPL-2.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
|
||||||
|
|
||||||
dcPage::check('categories');
|
|
||||||
|
|
||||||
$cat_id = '';
|
|
||||||
$cat_title = '';
|
|
||||||
$cat_url = '';
|
|
||||||
$cat_desc = '';
|
|
||||||
$cat_position = '';
|
|
||||||
|
|
||||||
$blog_settings = new dcSettings($core, $core->blog->id);
|
|
||||||
$blog_lang = $blog_settings->system->lang;
|
|
||||||
|
|
||||||
# Getting existing category
|
|
||||||
if (!empty($_REQUEST['id'])) {
|
|
||||||
try {
|
|
||||||
$rs = $core->blog->getCategory($_REQUEST['id']);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$core->error->flag() && !$rs->isEmpty()) {
|
|
||||||
$cat_id = (integer) $rs->cat_id;
|
|
||||||
$cat_title = $rs->cat_title;
|
|
||||||
$cat_url = $rs->cat_url;
|
|
||||||
$cat_desc = $rs->cat_desc;
|
|
||||||
}
|
|
||||||
unset($rs);
|
|
||||||
|
|
||||||
# Getting hierarchy information
|
|
||||||
$parents = $core->blog->getCategoryParents($cat_id);
|
|
||||||
$rs = $core->blog->getCategoryParent($cat_id);
|
|
||||||
$cat_parent = $rs->isEmpty() ? 0 : (integer) $rs->cat_id;
|
|
||||||
unset($rs);
|
|
||||||
|
|
||||||
# Allowed parents list
|
|
||||||
$children = $core->blog->getCategories(['start' => $cat_id]);
|
|
||||||
$allowed_parents = [__('Top level') => 0];
|
|
||||||
|
|
||||||
$p = [];
|
|
||||||
while ($children->fetch()) {
|
|
||||||
$p[$children->cat_id] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
$rs = $core->blog->getCategories();
|
|
||||||
while ($rs->fetch()) {
|
|
||||||
if (!isset($p[$rs->cat_id])) {
|
|
||||||
$allowed_parents[] = new formSelectOption(
|
|
||||||
str_repeat(' ', $rs->level - 1) . ($rs->level - 1 == 0 ? '' : '• ') . html::escapeHTML($rs->cat_title),
|
|
||||||
$rs->cat_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($rs);
|
|
||||||
|
|
||||||
# Allowed siblings list
|
|
||||||
$siblings = [];
|
|
||||||
$rs = $core->blog->getCategoryFirstChildren($cat_parent);
|
|
||||||
while ($rs->fetch()) {
|
|
||||||
if ($rs->cat_id != $cat_id) {
|
|
||||||
$siblings[html::escapeHTML($rs->cat_title)] = $rs->cat_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($rs);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Changing parent
|
|
||||||
if ($cat_id && isset($_POST['cat_parent'])) {
|
|
||||||
$new_parent = (integer) $_POST['cat_parent'];
|
|
||||||
if ($cat_parent != $new_parent) {
|
|
||||||
try {
|
|
||||||
$core->blog->setCategoryParent($cat_id, $new_parent);
|
|
||||||
dcPage::addSuccessNotice(__('The category has been successfully moved'));
|
|
||||||
$core->adminurl->redirect("admin.categories");
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Changing sibling
|
|
||||||
if ($cat_id && isset($_POST['cat_sibling'])) {
|
|
||||||
try {
|
|
||||||
$core->blog->setCategoryPosition($cat_id, (integer) $_POST['cat_sibling'], $_POST['cat_move']);
|
|
||||||
dcPage::addSuccessNotice(__('The category has been successfully moved'));
|
|
||||||
$core->adminurl->redirect("admin.categories");
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create or update a category
|
|
||||||
if (isset($_POST['cat_title'])) {
|
|
||||||
$cur = $core->con->openCursor($core->prefix . 'category');
|
|
||||||
|
|
||||||
$cur->cat_title = $cat_title = $_POST['cat_title'];
|
|
||||||
|
|
||||||
if (isset($_POST['cat_desc'])) {
|
|
||||||
$cur->cat_desc = $cat_desc = $_POST['cat_desc'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['cat_url'])) {
|
|
||||||
$cur->cat_url = $cat_url = $_POST['cat_url'];
|
|
||||||
} else {
|
|
||||||
$cur->cat_url = $cat_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
# Update category
|
|
||||||
if ($cat_id) {
|
|
||||||
# --BEHAVIOR-- adminBeforeCategoryUpdate
|
|
||||||
$core->callBehavior('adminBeforeCategoryUpdate', $cur, $cat_id);
|
|
||||||
|
|
||||||
$core->blog->updCategory($_POST['id'], $cur);
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminAfterCategoryUpdate
|
|
||||||
$core->callBehavior('adminAfterCategoryUpdate', $cur, $cat_id);
|
|
||||||
|
|
||||||
dcPage::addSuccessNotice(__('The category has been successfully updated.'));
|
|
||||||
|
|
||||||
$core->adminurl->redirect("admin.category", ['id' => $_POST['id']]);
|
|
||||||
}
|
|
||||||
# Create category
|
|
||||||
else {
|
|
||||||
# --BEHAVIOR-- adminBeforeCategoryCreate
|
|
||||||
$core->callBehavior('adminBeforeCategoryCreate', $cur);
|
|
||||||
|
|
||||||
$id = $core->blog->addCategory($cur, (integer) $_POST['new_cat_parent']);
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminAfterCategoryCreate
|
|
||||||
$core->callBehavior('adminAfterCategoryCreate', $cur, $id);
|
|
||||||
|
|
||||||
dcPage::addSuccessNotice(sprintf(__('The category "%s" has been successfully created.'),
|
|
||||||
html::escapeHTML($cur->cat_title)));
|
|
||||||
$core->adminurl->redirect("admin.categories");
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$title = $cat_id ? html::escapeHTML($cat_title) : __('New category');
|
|
||||||
|
|
||||||
$elements = [
|
|
||||||
html::escapeHTML($core->blog->name) => '',
|
|
||||||
__('Categories') => $core->adminurl->get("admin.categories")
|
|
||||||
];
|
|
||||||
if ($cat_id) {
|
|
||||||
while ($parents->fetch()) {
|
|
||||||
$elements[html::escapeHTML($parents->cat_title)] = $core->adminurl->get("admin.category", ['id' => $parents->cat_id]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$elements[$title] = '';
|
|
||||||
|
|
||||||
$category_editor = $core->auth->getOption('editor');
|
|
||||||
$rte_flag = true;
|
|
||||||
$rte_flags = @$core->auth->user_prefs->interface->rte_flags;
|
|
||||||
if (is_array($rte_flags) && in_array('cat_descr', $rte_flags)) {
|
|
||||||
$rte_flag = $rte_flags['cat_descr'];
|
|
||||||
}
|
|
||||||
|
|
||||||
dcPage::open($title,
|
|
||||||
dcPage::jsConfirmClose('category-form') .
|
|
||||||
dcPage::jsLoad('js/_category.js') .
|
|
||||||
($rte_flag ? $core->callBehavior('adminPostEditor', $category_editor['xhtml'], 'category', ['#cat_desc'], 'xhtml') : ''),
|
|
||||||
dcPage::breadcrumb($elements)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!empty($_GET['upd'])) {
|
|
||||||
dcPage::success(__('Category has been successfully updated.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<form action="' . $core->adminurl->get("admin.category") . '" method="post" id="category-form">' .
|
|
||||||
'<h3>' . __('Category information') . '</h3>' .
|
|
||||||
'<p><label class="required" for="cat_title"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Name:') . '</label> ' .
|
|
||||||
form::field('cat_title', 40, 255, [
|
|
||||||
'default' => html::escapeHTML($cat_title),
|
|
||||||
'extra_html' => 'required placeholder="' . __('Name') . '" lang="' . $blog_lang . '" spellcheck="true"'
|
|
||||||
]) .
|
|
||||||
'</p>';
|
|
||||||
if (!$cat_id) {
|
|
||||||
$rs = $core->blog->getCategories();
|
|
||||||
echo
|
|
||||||
'<p><label for="new_cat_parent">' . __('Parent:') . ' ' .
|
|
||||||
'<select id="new_cat_parent" name="new_cat_parent" >' .
|
|
||||||
'<option value="0">' . __('(none)') . '</option>';
|
|
||||||
while ($rs->fetch()) {
|
|
||||||
echo '<option value="' . $rs->cat_id . '" ' . (!empty($_POST['new_cat_parent']) && $_POST['new_cat_parent'] == $rs->cat_id ? 'selected="selected"' : '') . '>' .
|
|
||||||
str_repeat(' ', $rs->level - 1) . ($rs->level - 1 == 0 ? '' : '• ') . html::escapeHTML($rs->cat_title) . '</option>';
|
|
||||||
}
|
|
||||||
echo
|
|
||||||
'</select></label></p>';
|
|
||||||
unset($rs);
|
|
||||||
}
|
|
||||||
echo
|
|
||||||
'<div class="lockable">' .
|
|
||||||
'<p><label for="cat_url">' . __('URL:') . '</label> '
|
|
||||||
. form::field('cat_url', 40, 255, html::escapeHTML($cat_url)) .
|
|
||||||
'</p>' .
|
|
||||||
'<p class="form-note warn" id="note-cat-url">' .
|
|
||||||
__('Warning: If you set the URL manually, it may conflict with another category.') . '</p>' .
|
|
||||||
'</div>' .
|
|
||||||
|
|
||||||
'<p class="area"><label for="cat_desc">' . __('Description:') . '</label> ' .
|
|
||||||
form::textarea('cat_desc', 50, 8,
|
|
||||||
[
|
|
||||||
'default' => html::escapeHTML($cat_desc),
|
|
||||||
'extra_html' => 'lang="' . $blog_lang . '" spellcheck="true"'
|
|
||||||
]) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><input type="submit" accesskey="s" value="' . __('Save') . '" />' .
|
|
||||||
($cat_id ? form::hidden('id', $cat_id) : '') .
|
|
||||||
$core->formNonce() .
|
|
||||||
'</p>' .
|
|
||||||
'</form>';
|
|
||||||
|
|
||||||
if ($cat_id) {
|
|
||||||
echo
|
|
||||||
'<h3 class="border-top">' . __('Move this category') . '</h3>' .
|
|
||||||
'<div class="two-cols">' .
|
|
||||||
'<div class="col">' .
|
|
||||||
|
|
||||||
'<form action="' . $core->adminurl->get("admin.category") . '" method="post" class="fieldset">' .
|
|
||||||
'<h4>' . __('Category parent') . '</h4>' .
|
|
||||||
'<p><label for="cat_parent" class="classic">' . __('Parent:') . '</label> ' .
|
|
||||||
form::combo('cat_parent', $allowed_parents, $cat_parent) . '</p>' .
|
|
||||||
'<p><input type="submit" accesskey="s" value="' . __('Save') . '" />' .
|
|
||||||
form::hidden(['id'], $cat_id) . $core->formNonce() . '</p>' .
|
|
||||||
'</form>' .
|
|
||||||
'</div>';
|
|
||||||
|
|
||||||
if (count($siblings) > 0) {
|
|
||||||
echo
|
|
||||||
'<div class="col">' .
|
|
||||||
'<form action="' . $core->adminurl->get("admin.category") . '" method="post" class="fieldset">' .
|
|
||||||
'<h4>' . __('Category sibling') . '</h4>' .
|
|
||||||
'<p><label class="classic" for="cat_sibling">' . __('Move current category') . '</label> ' .
|
|
||||||
form::combo('cat_move', [__('before') => 'before', __('after') => 'after'],
|
|
||||||
['extra_html' => 'title="' . __('position: ') . '"']) . ' ' .
|
|
||||||
form::combo('cat_sibling', $siblings) . '</p>' .
|
|
||||||
'<p><input type="submit" accesskey="s" value="' . __('Save') . '" />' .
|
|
||||||
form::hidden(['id'], $cat_id) . $core->formNonce() . '</p>' .
|
|
||||||
'</form>' .
|
|
||||||
'</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
dcPage::helpBlock('core_category');
|
|
||||||
dcPage::close();
|
|
||||||
@ -1,252 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Backend
|
|
||||||
*
|
|
||||||
* @copyright Olivier Meunier & Association Dotclear
|
|
||||||
* @copyright GPL-2.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
|
||||||
|
|
||||||
dcPage::check('usage,contentadmin');
|
|
||||||
|
|
||||||
$comment_id = null;
|
|
||||||
$comment_dt = '';
|
|
||||||
$comment_author = '';
|
|
||||||
$comment_email = '';
|
|
||||||
$comment_site = '';
|
|
||||||
$comment_content = '';
|
|
||||||
$comment_ip = '';
|
|
||||||
$comment_status = '';
|
|
||||||
$comment_trackback = 0;
|
|
||||||
$comment_spam_status = '';
|
|
||||||
|
|
||||||
$comment_editor = $core->auth->getOption('editor');
|
|
||||||
|
|
||||||
# Status combo
|
|
||||||
$status_combo = dcAdminCombos::getCommentStatusescombo();
|
|
||||||
|
|
||||||
# Adding comment (comming from post form, comments tab)
|
|
||||||
if (!empty($_POST['add']) && !empty($_POST['post_id'])) {
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$rs = $core->blog->getPosts(['post_id' => $_POST['post_id'], 'post_type' => '']);
|
|
||||||
|
|
||||||
if ($rs->isEmpty()) {
|
|
||||||
throw new Exception(__('Entry does not exist.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$cur = $core->con->openCursor($core->prefix . 'comment');
|
|
||||||
|
|
||||||
$cur->comment_author = $_POST['comment_author'];
|
|
||||||
$cur->comment_email = html::clean($_POST['comment_email']);
|
|
||||||
$cur->comment_site = html::clean($_POST['comment_site']);
|
|
||||||
$cur->comment_content = $core->HTMLfilter($_POST['comment_content']);
|
|
||||||
$cur->post_id = (integer) $_POST['post_id'];
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminBeforeCommentCreate
|
|
||||||
$core->callBehavior('adminBeforeCommentCreate', $cur);
|
|
||||||
|
|
||||||
$comment_id = $core->blog->addComment($cur);
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminAfterCommentCreate
|
|
||||||
$core->callBehavior('adminAfterCommentCreate', $cur, $comment_id);
|
|
||||||
|
|
||||||
dcPage::addSuccessNotice(__('Comment has been successfully created.'));
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
http::redirect($core->getPostAdminURL($rs->post_type, $rs->post_id, false) . '&co=1');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($_REQUEST['id'])) {
|
|
||||||
$params['comment_id'] = $_REQUEST['id'];
|
|
||||||
|
|
||||||
try {
|
|
||||||
$rs = $core->blog->getComments($params);
|
|
||||||
if (!$rs->isEmpty()) {
|
|
||||||
$comment_id = $rs->comment_id;
|
|
||||||
$post_id = $rs->post_id;
|
|
||||||
$post_type = $rs->post_type;
|
|
||||||
$post_title = $rs->post_title;
|
|
||||||
$comment_dt = $rs->comment_dt;
|
|
||||||
$comment_author = $rs->comment_author;
|
|
||||||
$comment_email = $rs->comment_email;
|
|
||||||
$comment_site = $rs->comment_site;
|
|
||||||
$comment_content = $rs->comment_content;
|
|
||||||
$comment_ip = $rs->comment_ip;
|
|
||||||
$comment_status = $rs->comment_status;
|
|
||||||
$comment_trackback = (boolean) $rs->comment_trackback;
|
|
||||||
$comment_spam_status = $rs->comment_spam_status;
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$comment_id && !$core->error->flag()) {
|
|
||||||
$core->error->add(__('No comments'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$core->error->flag() && isset($rs)) {
|
|
||||||
$can_edit = $can_delete = $can_publish = $core->auth->check('contentadmin', $core->blog->id);
|
|
||||||
|
|
||||||
if (!$core->auth->check('contentadmin', $core->blog->id) && $core->auth->userID() == $rs->user_id) {
|
|
||||||
$can_edit = true;
|
|
||||||
if ($core->auth->check('delete', $core->blog->id)) {
|
|
||||||
$can_delete = true;
|
|
||||||
}
|
|
||||||
if ($core->auth->check('publish', $core->blog->id)) {
|
|
||||||
$can_publish = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# update comment
|
|
||||||
if (!empty($_POST['update']) && $can_edit) {
|
|
||||||
$cur = $core->con->openCursor($core->prefix . 'comment');
|
|
||||||
|
|
||||||
$cur->comment_author = $_POST['comment_author'];
|
|
||||||
$cur->comment_email = html::clean($_POST['comment_email']);
|
|
||||||
$cur->comment_site = html::clean($_POST['comment_site']);
|
|
||||||
$cur->comment_content = $core->HTMLfilter($_POST['comment_content']);
|
|
||||||
|
|
||||||
if (isset($_POST['comment_status'])) {
|
|
||||||
$cur->comment_status = (integer) $_POST['comment_status'];
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
# --BEHAVIOR-- adminBeforeCommentUpdate
|
|
||||||
$core->callBehavior('adminBeforeCommentUpdate', $cur, $comment_id);
|
|
||||||
|
|
||||||
$core->blog->updComment($comment_id, $cur);
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminAfterCommentUpdate
|
|
||||||
$core->callBehavior('adminAfterCommentUpdate', $cur, $comment_id);
|
|
||||||
|
|
||||||
dcPage::addSuccessNotice(__('Comment has been successfully updated.'));
|
|
||||||
$core->adminurl->redirect("admin.comment", ['id' => $comment_id]);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($_POST['delete']) && $can_delete) {
|
|
||||||
try {
|
|
||||||
# --BEHAVIOR-- adminBeforeCommentDelete
|
|
||||||
$core->callBehavior('adminBeforeCommentDelete', $comment_id);
|
|
||||||
|
|
||||||
$core->blog->delComment($comment_id);
|
|
||||||
|
|
||||||
dcPage::addSuccessNotice(__('Comment has been successfully deleted.'));
|
|
||||||
http::redirect($core->getPostAdminURL($rs->post_type, $rs->post_id) . '&co=1', false);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$can_edit) {
|
|
||||||
$core->error->add(__("You can't edit this comment."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* DISPLAY
|
|
||||||
-------------------------------------------------------- */
|
|
||||||
if ($comment_id) {
|
|
||||||
$breadcrumb = dcPage::breadcrumb(
|
|
||||||
[
|
|
||||||
html::escapeHTML($core->blog->name) => '',
|
|
||||||
html::escapeHTML($post_title) => $core->getPostAdminURL($post_type, $post_id) . '&co=1#c' . $comment_id,
|
|
||||||
__('Edit comment') => ''
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
$breadcrumb = dcPage::breadcrumb(
|
|
||||||
[
|
|
||||||
html::escapeHTML($core->blog->name) => '',
|
|
||||||
html::escapeHTML($post_title) => $core->getPostAdminURL($post_type, $post_id),
|
|
||||||
__('Edit comment') => ''
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
dcPage::open(__('Edit comment'),
|
|
||||||
dcPage::jsConfirmClose('comment-form') .
|
|
||||||
dcPage::jsLoad('js/_comment.js') .
|
|
||||||
$core->callBehavior('adminPostEditor', $comment_editor['xhtml'], 'comment', ['#comment_content'], 'xhtml') .
|
|
||||||
# --BEHAVIOR-- adminCommentHeaders
|
|
||||||
$core->callBehavior('adminCommentHeaders'),
|
|
||||||
$breadcrumb
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($comment_id) {
|
|
||||||
if (!empty($_GET['upd'])) {
|
|
||||||
dcPage::success(__('Comment has been successfully updated.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$comment_mailto = '';
|
|
||||||
if ($comment_email) {
|
|
||||||
$comment_mailto = '<a href="mailto:' . html::escapeHTML($comment_email)
|
|
||||||
. '?subject=' . rawurlencode(sprintf(__('Your comment on my blog %s'), $core->blog->name))
|
|
||||||
. '&body='
|
|
||||||
. rawurlencode(sprintf(__("Hi!\n\nYou wrote a comment on:\n%s\n\n\n"), $rs->getPostURL()))
|
|
||||||
. '">' . __('Send an e-mail') . '</a>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<form action="' . $core->adminurl->get("admin.comment") . '" method="post" id="comment-form">' .
|
|
||||||
'<div class="fieldset">' .
|
|
||||||
'<h3>' . __('Information collected') . '</h3>' .
|
|
||||||
'<p>' . __('IP address:') . ' ' .
|
|
||||||
'<a href="' . $core->adminurl->get("admin.comments", ['ip' => $comment_ip]) . '">' . $comment_ip . '</a></p>' .
|
|
||||||
|
|
||||||
'<p>' . __('Date:') . ' ' .
|
|
||||||
dt::dt2str(__('%Y-%m-%d %H:%M'), $comment_dt) . '</p>' .
|
|
||||||
'</div>' .
|
|
||||||
|
|
||||||
'<h3>' . __('Comment submitted') . '</h3>' .
|
|
||||||
'<p><label for="comment_author" class="required"><abbr title="' . __('Required field') . '">*</abbr>' . __('Author:') . '</label>' .
|
|
||||||
form::field('comment_author', 30, 255, [
|
|
||||||
'default' => html::escapeHTML($comment_author),
|
|
||||||
'extra_html' => 'required placeholder="' . __('Author') . '"'
|
|
||||||
]) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="comment_email">' . __('Email:') . '</label>' .
|
|
||||||
form::email('comment_email', 30, 255, html::escapeHTML($comment_email)) .
|
|
||||||
'<span>' . $comment_mailto . '</span>' .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="comment_site">' . __('Web site:') . '</label>' .
|
|
||||||
form::url('comment_site', 30, 255, html::escapeHTML($comment_site)) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="comment_status">' . __('Status:') . '</label>' .
|
|
||||||
form::combo('comment_status', $status_combo,
|
|
||||||
['default' => $comment_status, 'disabled' => !$can_publish]) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminAfterCommentDesc
|
|
||||||
$core->callBehavior('adminAfterCommentDesc', $rs) .
|
|
||||||
|
|
||||||
'<p class="area"><label for="comment_content">' . __('Comment:') . '</label> ' .
|
|
||||||
form::textarea('comment_content', 50, 10,
|
|
||||||
[
|
|
||||||
'default' => html::escapeHTML($comment_content),
|
|
||||||
'extra_html' => 'lang="' . $core->auth->getInfo('user_lang') . '" spellcheck="true"'
|
|
||||||
]) .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p>' . form::hidden('id', $comment_id) .
|
|
||||||
$core->formNonce() .
|
|
||||||
'<input type="submit" accesskey="s" name="update" value="' . __('Save') . '" /> ';
|
|
||||||
|
|
||||||
if ($can_delete) {
|
|
||||||
echo '<input type="submit" class="delete" name="delete" value="' . __('Delete') . '" />';
|
|
||||||
}
|
|
||||||
echo
|
|
||||||
'</p>' .
|
|
||||||
'</form>';
|
|
||||||
}
|
|
||||||
|
|
||||||
dcPage::helpBlock('core_comments');
|
|
||||||
dcPage::close();
|
|
||||||
@ -1,302 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Backend
|
|
||||||
*
|
|
||||||
* @copyright Olivier Meunier & Association Dotclear
|
|
||||||
* @copyright GPL-2.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
|
||||||
|
|
||||||
dcPage::check('usage,contentadmin');
|
|
||||||
|
|
||||||
if (!empty($_POST['delete_all_spam'])) {
|
|
||||||
try {
|
|
||||||
$core->blog->delJunkComments();
|
|
||||||
$_SESSION['comments_del_spam'] = true;
|
|
||||||
$core->adminurl->redirect("admin.comments");
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Creating filter combo boxes
|
|
||||||
# Filter form we'll put in html_block
|
|
||||||
$status_combo = array_merge(
|
|
||||||
['-' => ''],
|
|
||||||
dcAdminCombos::getCommentStatusescombo()
|
|
||||||
);
|
|
||||||
|
|
||||||
$type_combo = [
|
|
||||||
'-' => '',
|
|
||||||
__('Comment') => 'co',
|
|
||||||
__('Trackback') => 'tb'
|
|
||||||
];
|
|
||||||
|
|
||||||
$sortby_combo = [
|
|
||||||
__('Date') => 'comment_dt',
|
|
||||||
__('Entry title') => 'post_title',
|
|
||||||
__('Entry date') => 'post_dt',
|
|
||||||
__('Author') => 'comment_author',
|
|
||||||
__('Status') => 'comment_status'
|
|
||||||
];
|
|
||||||
|
|
||||||
$sortby_lex = [
|
|
||||||
// key in sorty_combo (see above) => field in SQL request
|
|
||||||
'post_title' => 'post_title',
|
|
||||||
'comment_author' => 'comment_author',
|
|
||||||
'comment_spam_filter' => 'comment_spam_filter'];
|
|
||||||
|
|
||||||
$order_combo = [
|
|
||||||
__('Descending') => 'desc',
|
|
||||||
__('Ascending') => 'asc'
|
|
||||||
];
|
|
||||||
|
|
||||||
/* Get comments
|
|
||||||
-------------------------------------------------------- */
|
|
||||||
$author = isset($_GET['author']) ? $_GET['author'] : '';
|
|
||||||
$status = isset($_GET['status']) ? $_GET['status'] : '';
|
|
||||||
$type = !empty($_GET['type']) ? $_GET['type'] : '';
|
|
||||||
$sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'comment_dt';
|
|
||||||
$order = !empty($_GET['order']) ? $_GET['order'] : 'desc';
|
|
||||||
$ip = !empty($_GET['ip']) ? $_GET['ip'] : '';
|
|
||||||
$email = !empty($_GET['email']) ? $_GET['email'] : '';
|
|
||||||
$site = !empty($_GET['site']) ? $_GET['site'] : '';
|
|
||||||
|
|
||||||
$with_spam = $author || $status || $type || $sortby != 'comment_dt' || $order != 'desc' || $ip;
|
|
||||||
|
|
||||||
$show_filters = false;
|
|
||||||
|
|
||||||
$page = !empty($_GET['page']) ? max(1, (integer) $_GET['page']) : 1;
|
|
||||||
$nb_per_page = 30;
|
|
||||||
|
|
||||||
if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) {
|
|
||||||
if ($nb_per_page != (integer) $_GET['nb']) {
|
|
||||||
$show_filters = true;
|
|
||||||
}
|
|
||||||
$nb_per_page = (integer) $_GET['nb'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$params['limit'] = [(($page - 1) * $nb_per_page), $nb_per_page];
|
|
||||||
$params['no_content'] = true;
|
|
||||||
|
|
||||||
# Author filter
|
|
||||||
if ($author !== '') {
|
|
||||||
$params['q_author'] = $author;
|
|
||||||
$show_filters = true;
|
|
||||||
} else {
|
|
||||||
$author = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
# - Type filter
|
|
||||||
if ($type == 'tb' || $type == 'co') {
|
|
||||||
$params['comment_trackback'] = ($type == 'tb');
|
|
||||||
$show_filters = true;
|
|
||||||
} else {
|
|
||||||
$type = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
# - Status filter
|
|
||||||
if ($status !== '' && in_array($status, $status_combo)) {
|
|
||||||
$params['comment_status'] = $status;
|
|
||||||
$show_filters = true;
|
|
||||||
} elseif (!$with_spam) {
|
|
||||||
$params['comment_status_not'] = -2;
|
|
||||||
$status = '';
|
|
||||||
} else {
|
|
||||||
$status = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
# - IP filter
|
|
||||||
if ($ip) {
|
|
||||||
$params['comment_ip'] = $ip;
|
|
||||||
$show_filters = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
# - email filter
|
|
||||||
if ($email) {
|
|
||||||
$params['comment_email'] = $email;
|
|
||||||
$show_filters = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
# - site filter
|
|
||||||
if ($site) {
|
|
||||||
$params['comment_site'] = $site;
|
|
||||||
$show_filters = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add some sort order if spams displayed
|
|
||||||
if ($with_spam || ($status == -2)) {
|
|
||||||
$sortby_combo[__('IP')] = 'comment_ip';
|
|
||||||
$sortby_combo[__('Spam filter')] = 'comment_spam_filter';
|
|
||||||
}
|
|
||||||
|
|
||||||
# Sortby and order filter
|
|
||||||
if ($sortby !== '' && in_array($sortby, $sortby_combo)) {
|
|
||||||
if (array_key_exists($sortby, $sortby_lex)) {
|
|
||||||
$params['order'] = $core->con->lexFields($sortby_lex[$sortby]);
|
|
||||||
} else {
|
|
||||||
$params['order'] = $sortby;
|
|
||||||
}
|
|
||||||
if ($order !== '' && in_array($order, $order_combo)) {
|
|
||||||
$params['order'] .= ' ' . $order;
|
|
||||||
} else {
|
|
||||||
$order = 'desc';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($sortby != 'comment_dt' || $order != 'desc') {
|
|
||||||
$show_filters = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$sortby = 'comment_dt';
|
|
||||||
$order = 'desc';
|
|
||||||
}
|
|
||||||
|
|
||||||
# Actions combo box
|
|
||||||
$combo_action = [];
|
|
||||||
$default = '';
|
|
||||||
if ($core->auth->check('delete,contentadmin', $core->blog->id) && $status == -2) {
|
|
||||||
$default = 'delete';
|
|
||||||
}
|
|
||||||
|
|
||||||
$comments_actions_page = new dcCommentsActionsPage($core, $core->adminurl->get("admin.comments"));
|
|
||||||
|
|
||||||
if ($comments_actions_page->process()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get comments
|
|
||||||
-------------------------------------------------------- */
|
|
||||||
try {
|
|
||||||
$comments = $core->blog->getComments($params);
|
|
||||||
$counter = $core->blog->getComments($params, true);
|
|
||||||
$comment_list = new adminCommentList($core, $comments, $counter->f(0));
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$core->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* DISPLAY
|
|
||||||
-------------------------------------------------------- */
|
|
||||||
|
|
||||||
dcPage::open(__('Comments and trackbacks'),
|
|
||||||
dcPage::jsLoad('js/_comments.js') . dcPage::jsFilterControl($show_filters),
|
|
||||||
dcPage::breadcrumb(
|
|
||||||
[
|
|
||||||
html::escapeHTML($core->blog->name) => '',
|
|
||||||
__('Comments and trackbacks') => ''
|
|
||||||
])
|
|
||||||
);
|
|
||||||
if (!empty($_GET['upd'])) {
|
|
||||||
dcPage::success(__('Selected comments have been successfully updated.'));
|
|
||||||
} elseif (!empty($_GET['del'])) {
|
|
||||||
dcPage::success(__('Selected comments have been successfully deleted.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$core->error->flag()) {
|
|
||||||
if (isset($_SESSION['comments_del_spam'])) {
|
|
||||||
dcPage::message(__('Spam comments have been successfully deleted.'));
|
|
||||||
unset($_SESSION['comments_del_spam']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$spam_count = $core->blog->getComments(['comment_status' => -2], true)->f(0);
|
|
||||||
if ($spam_count > 0) {
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<form action="' . $core->adminurl->get("admin.comments") . '" method="post" class="fieldset">';
|
|
||||||
|
|
||||||
if (!$with_spam || ($status != -2)) {
|
|
||||||
if ($spam_count == 1) {
|
|
||||||
echo '<p>' . sprintf(__('You have one spam comment.'), '<strong>' . $spam_count . '</strong>') . ' ' .
|
|
||||||
'<a href="' . $core->adminurl->get("admin.comments", ['status' => -2]) . '">' . __('Show it.') . '</a></p>';
|
|
||||||
} elseif ($spam_count > 1) {
|
|
||||||
echo '<p>' . sprintf(__('You have %s spam comments.'), '<strong>' . $spam_count . '</strong>') . ' ' .
|
|
||||||
'<a href="' . $core->adminurl->get("admin.comments", ['status' => -2]) . '">' . __('Show them.') . '</a></p>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<p>' .
|
|
||||||
$core->formNonce() .
|
|
||||||
'<input name="delete_all_spam" class="delete" type="submit" value="' . __('Delete all spams') . '" /></p>';
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminCommentsSpamForm
|
|
||||||
$core->callBehavior('adminCommentsSpamForm', $core);
|
|
||||||
|
|
||||||
echo '</form>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<form action="' . $core->adminurl->get("admin.comments") . '" method="get" id="filters-form">' .
|
|
||||||
'<h3 class="out-of-screen-if-js">' . __('Show filters and display options') . '</h3>' .
|
|
||||||
|
|
||||||
'<div class="table">' .
|
|
||||||
'<div class="cell">' .
|
|
||||||
'<h4>' . __('Filters') . '</h4>' .
|
|
||||||
'<p><label for="type" class="ib">' . __('Type:') . '</label> ' .
|
|
||||||
form::combo('type', $type_combo, $type) . '</p> ' .
|
|
||||||
'<p><label for="status" class="ib">' . __('Status:') . '</label> ' .
|
|
||||||
form::combo('status', $status_combo, $status) . '</p>' .
|
|
||||||
'</div>' .
|
|
||||||
|
|
||||||
'<div class="cell filters-sibling-cell">' .
|
|
||||||
'<p><label for="author" class="ib">' . __('Author:') . '</label> ' .
|
|
||||||
form::field('author', 20, 255, html::escapeHTML($author)) . '</p>' .
|
|
||||||
'<p><label for="ip" class="ib">' . __('IP address:') . '</label> ' .
|
|
||||||
form::field('ip', 20, 39, html::escapeHTML($ip)) . '</p>' .
|
|
||||||
'<p><label for="email" class="ib">' . __('Email:') . '</label> ' .
|
|
||||||
form::field('email', 20, 255, html::escapeHTML($email)) . '</p>' .
|
|
||||||
'<p><label for="site" class="ib">' . __('Web site:') . '</label> ' .
|
|
||||||
form::field('site', 20, 255, html::escapeHTML($site)) . '</p>' .
|
|
||||||
'</div>' .
|
|
||||||
|
|
||||||
'<div class="cell filters-options">' .
|
|
||||||
'<h4>' . __('Display options') . '</h4>' .
|
|
||||||
'<p><label for="sortby" class="ib">' . __('Order by:') . '</label> ' .
|
|
||||||
form::combo('sortby', $sortby_combo, $sortby) . '</p>' .
|
|
||||||
'<p><label for="order" class="ib">' . __('Sort:') . '</label> ' .
|
|
||||||
form::combo('order', $order_combo, $order) . '</p>' .
|
|
||||||
'<p><span class="label ib">' . __('Show') . '</span> <label for="nb" class="classic">' .
|
|
||||||
form::number('nb', 0, 999, $nb_per_page) . ' ' .
|
|
||||||
__('comments per page') . '</label></p>' .
|
|
||||||
'</div>' .
|
|
||||||
|
|
||||||
'</div>' .
|
|
||||||
'<p><input type="submit" value="' . __('Apply filters and display options') . '" />' .
|
|
||||||
'<br class="clear" /></p>' . //Opera sucks
|
|
||||||
'</form>';
|
|
||||||
|
|
||||||
# Show comments
|
|
||||||
$comment_list->display($page, $nb_per_page,
|
|
||||||
'<form action="' . $core->adminurl->get("admin.comments") . '" method="post" id="form-comments">' .
|
|
||||||
|
|
||||||
'%s' .
|
|
||||||
|
|
||||||
'<div class="two-cols">' .
|
|
||||||
'<p class="col checkboxes-helpers"></p>' .
|
|
||||||
|
|
||||||
'<p class="col right"><label for="action" class="classic">' . __('Selected comments action:') . '</label> ' .
|
|
||||||
form::combo('action', $comments_actions_page->getCombo(),
|
|
||||||
['default' => $default, 'extra_html' => 'title="' . __('Actions') . '"']) .
|
|
||||||
$core->formNonce() .
|
|
||||||
'<input id="do-action" type="submit" value="' . __('ok') . '" /></p>' .
|
|
||||||
form::hidden(['type'], $type) .
|
|
||||||
form::hidden(['sortby'], $sortby) .
|
|
||||||
form::hidden(['order'], $order) .
|
|
||||||
form::hidden(['author'], html::escapeHTML(preg_replace('/%/', '%%', $author))) .
|
|
||||||
form::hidden(['status'], $status) .
|
|
||||||
form::hidden(['ip'], preg_replace('/%/', '%%', $ip)) .
|
|
||||||
form::hidden(['page'], $page) .
|
|
||||||
form::hidden(['nb'], $nb_per_page) .
|
|
||||||
form::hidden(['email'], html::escapeHTML(preg_replace('/%/', '%%', $email))) .
|
|
||||||
form::hidden(['site'], html::escapeHTML(preg_replace('/%/', '%%', $site))) .
|
|
||||||
'</div>' .
|
|
||||||
|
|
||||||
'</form>',
|
|
||||||
$show_filters,
|
|
||||||
($with_spam || ($status == -2))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
dcPage::helpBlock('core_comments');
|
|
||||||
dcPage::close();
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Backend
|
|
||||||
*
|
|
||||||
* @copyright Olivier Meunier & Association Dotclear
|
|
||||||
* @copyright GPL-2.0-only
|
|
||||||
*
|
|
||||||
* @deprecated It is only used for plugins compatibility
|
|
||||||
*/
|
|
||||||
|
|
||||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
|
||||||
|
|
||||||
dcPage::check('usage,contentadmin');
|
|
||||||
|
|
||||||
if (isset($_REQUEST['redir'])) {
|
|
||||||
$u = explode('?', $_REQUEST['redir']);
|
|
||||||
$uri = $u[0];
|
|
||||||
if (isset($u[1])) {
|
|
||||||
parse_str($u[1], $args);
|
|
||||||
}
|
|
||||||
$args['redir'] = $_REQUEST['redir'];
|
|
||||||
} else {
|
|
||||||
$uri = $core->adminurl->get("admin.comments");
|
|
||||||
$args = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$comments_actions_page = new dcCommentsActionsPage($core, $uri, $args);
|
|
||||||
$comments_actions_page->setEnableRedirSelection(false);
|
|
||||||
$comments_actions_page->process();
|
|
||||||
@ -1,106 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Backend
|
|
||||||
*
|
|
||||||
* @copyright Olivier Meunier & Association Dotclear
|
|
||||||
* @copyright GPL-2.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
// From: https://github.com/nico3333fr/CSP-useful
|
|
||||||
//
|
|
||||||
// Note: this script requires PHP ≥ 5.4.
|
|
||||||
// Inspired from https://mathiasbynens.be/notes/csp-reports
|
|
||||||
|
|
||||||
// Dareboost wants it? Not a problem.
|
|
||||||
header('X-Content-Type-Options: "nosniff"');
|
|
||||||
|
|
||||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
|
||||||
|
|
||||||
// Specify admin CSP log file if necessary
|
|
||||||
if (!defined('LOGFILE')) {
|
|
||||||
define('LOGFILE', path::real(DC_VAR) . '/csp/csp_report.json');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the raw POST data
|
|
||||||
$data = file_get_contents('php://input');
|
|
||||||
|
|
||||||
// Only continue if it’s valid JSON that is not just `null`, `0`, `false` or an
|
|
||||||
// empty string, i.e. if it could be a CSP violation report.
|
|
||||||
if ($data = json_decode($data, true)) {
|
|
||||||
|
|
||||||
// get source-file and blocked-URI to perform some tests
|
|
||||||
$source_file = isset($data['csp-report']['source-file']) ? $data['csp-report']['source-file'] : '';
|
|
||||||
$line_number = isset($data['csp-report']['line-number']) ? $data['csp-report']['line-number'] : '';
|
|
||||||
$blocked_uri = isset($data['csp-report']['blocked-uri']) ? $data['csp-report']['blocked-uri'] : '';
|
|
||||||
$document_uri = isset($data['csp-report']['document-uri']) ? $data['csp-report']['document-uri'] : '';
|
|
||||||
$violated_directive = isset($data['csp-report']['violated-directive']) ? $data['csp-report']['violated-directive'] : '';
|
|
||||||
|
|
||||||
if (
|
|
||||||
// avoid false positives notifications coming from Chrome extensions (Wappalyzer, MuteTab, etc.)
|
|
||||||
// bug here https://code.google.com/p/chromium/issues/detail?id=524356
|
|
||||||
strpos($source_file, 'chrome-extension://') === false
|
|
||||||
|
|
||||||
// avoid false positives notifications coming from Safari extensions (diigo, evernote, etc.)
|
|
||||||
&& strpos($source_file, 'safari-extension://') === false
|
|
||||||
&& strpos($blocked_uri, 'safari-extension://') === false
|
|
||||||
|
|
||||||
// search engine extensions ?
|
|
||||||
&& strpos($source_file, 'se-extension://') === false
|
|
||||||
|
|
||||||
// added by browsers in webviews
|
|
||||||
&& strpos($blocked_uri, 'webviewprogressproxy://') === false
|
|
||||||
|
|
||||||
// Google Search App see for details https://github.com/nico3333fr/CSP-useful/commit/ecc8f9b0b379ae643bc754d2db33c8b47e185fd1
|
|
||||||
&& strpos($blocked_uri, 'gsa://onpageload') === false
|
|
||||||
|
|
||||||
) {
|
|
||||||
// Prepare report data (hash => info)
|
|
||||||
$hash = hash('md5', $blocked_uri . $document_uri . $source_file . $line_number . $violated_directive);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Check report dir (create it if necessary)
|
|
||||||
files::makeDir(dirname(LOGFILE), true);
|
|
||||||
|
|
||||||
// Check if report is not already stored in log file
|
|
||||||
$contents = '';
|
|
||||||
if (file_exists(LOGFILE)) {
|
|
||||||
$contents = file_get_contents(LOGFILE);
|
|
||||||
if ($contents && $contents != '') {
|
|
||||||
if (substr($contents, -1) == ',') {
|
|
||||||
// Remove final comma if present
|
|
||||||
$contents = substr($contents, 0, -1);
|
|
||||||
}
|
|
||||||
if ($contents != '') {
|
|
||||||
$list = json_decode('[' . $contents . ']', true);
|
|
||||||
if (is_array($list)) {
|
|
||||||
foreach ($list as $idx => $value) {
|
|
||||||
if (isset($value['hash']) && $value['hash'] == $hash) {
|
|
||||||
// Already stored, ignore
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add report to the file
|
|
||||||
if (!($fp = @fopen(LOGFILE, 'a'))) {
|
|
||||||
// Unable to open file, ignore
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prettify the JSON-formatted data
|
|
||||||
$violation = array_merge(['hash' => $hash], $data['csp-report']);
|
|
||||||
$output = json_encode($violation, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
|
||||||
|
|
||||||
// The file content will have to be enclosed in brackets [] before
|
|
||||||
// beeing decoded with json_decoded(<content>,true);
|
|
||||||
fprintf($fp, ($contents != '' ? ',' : '') . '%s', $output);
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
# -- BEGIN LICENSE BLOCK ---------------------------------------
|
|
||||||
#
|
|
||||||
# This file is part of Dotclear 2.
|
|
||||||
#
|
|
||||||
# Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear
|
|
||||||
# Licensed under the GPL version 2.0 license.
|
|
||||||
# See LICENSE file or
|
|
||||||
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
||||||
#
|
|
||||||
# -- END LICENSE BLOCK -----------------------------------------
|
|
||||||
|
|
||||||
# Delete users
|
|
||||||
if (!empty($_REQUEST['dispatch_action']))
|
|
||||||
{
|
|
||||||
if ($_REQUEST['dispatch_action'] == 'deleteuser')
|
|
||||||
{
|
|
||||||
if (!empty($_REQUEST['user_id'])) {
|
|
||||||
$delete_users = $_REQUEST['user_id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
include dirname(__FILE__).'/users.php';
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
elseif ($_REQUEST['dispatch_action'] == 'setpermissions')
|
|
||||||
{
|
|
||||||
include dirname(__FILE__).'/permissions_blog.php';
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '<p>What the hell are you doing here?</p>';
|
|
||||||
exit;
|
|
||||||
?>
|
|
||||||
@ -1,95 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Backend
|
|
||||||
*
|
|
||||||
* @copyright Olivier Meunier & Association Dotclear
|
|
||||||
* @copyright GPL-2.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
require dirname(__FILE__) . '/../inc/admin/prepend.php';
|
|
||||||
|
|
||||||
dcPage::check('usage,contentadmin');
|
|
||||||
|
|
||||||
$helpPage = function (...$args) {
|
|
||||||
$ret = ['content' => '', 'title' => ''];
|
|
||||||
|
|
||||||
if (empty($args)) {
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
global $__resources;
|
|
||||||
if (empty($__resources['help'])) {
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
$content = '';
|
|
||||||
$title = '';
|
|
||||||
foreach ($args as $v) {
|
|
||||||
if (is_object($v) && isset($v->content)) {
|
|
||||||
$content .= $v->content;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($__resources['help'][$v])) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$f = $__resources['help'][$v];
|
|
||||||
if (!file_exists($f) || !is_readable($f)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$fc = file_get_contents($f);
|
|
||||||
if (preg_match('|<body[^>]*?>(.*?)</body>|ms', $fc, $matches)) {
|
|
||||||
$content .= $matches[1];
|
|
||||||
if (preg_match('|<title[^>]*?>(.*?)</title>|ms', $fc, $matches)) {
|
|
||||||
$title = $matches[1];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$content .= $fc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trim($content) == '') {
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
$ret['content'] = $content;
|
|
||||||
if ($title != '') {
|
|
||||||
$ret['title'] = $title;
|
|
||||||
}
|
|
||||||
return $ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
$help_page = !empty($_GET['page']) ? html::escapeHTML($_GET['page']) : 'index';
|
|
||||||
$content_array = $helpPage($help_page);
|
|
||||||
if (($content_array['content'] == '') || ($help_page == 'index')) {
|
|
||||||
$content_array = $helpPage('index');
|
|
||||||
}
|
|
||||||
if ($content_array['title'] != '') {
|
|
||||||
$breadcrumb = dcPage::breadcrumb(
|
|
||||||
[
|
|
||||||
__('Global help') => $core->adminurl->get("admin.help"),
|
|
||||||
$content_array['title'] => ''
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
$breadcrumb = dcPage::breadcrumb(
|
|
||||||
[
|
|
||||||
__('Global help') => ''
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* DISPLAY
|
|
||||||
-------------------------------------------------------- */
|
|
||||||
dcPage::open(__('Global help'),
|
|
||||||
dcPage::jsPageTabs('first-step'),
|
|
||||||
$breadcrumb
|
|
||||||
);
|
|
||||||
|
|
||||||
echo $content_array['content'];
|
|
||||||
|
|
||||||
// Prevents global help link display
|
|
||||||
$GLOBALS['__resources']['ctxhelp'] = true;
|
|
||||||
|
|
||||||
dcPage::close();
|
|
||||||
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 257 B |
|
Before Width: | Height: | Size: 146 B |
@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><title>attachment</title><path d="M9.5 19.75a4.25 4.25 0 0 1-4.25-4.25v-6.5a2.75 2.75 0 0 1 5.5 0v6h-1.5v-6a1.25 1.25 0 0 0-2.5 0v6.5a2.75 2.75 0 0 0 5.5 0v-11.5a2.25 2.25 0 0 0-4.5 0v1h-1.5v-1a3.75 3.75 0 0 1 7.5 0v11.5a4.25 4.25 0 0 1-4.25 4.25z" fill="#ff0000"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 332 B |
|
Before Width: | Height: | Size: 109 B |
|
Before Width: | Height: | Size: 166 B |
|
Before Width: | Height: | Size: 90 B |
|
Before Width: | Height: | Size: 586 B |
|
Before Width: | Height: | Size: 149 B |
|
Before Width: | Height: | Size: 152 B |
|
Before Width: | Height: | Size: 226 B |
|
Before Width: | Height: | Size: 601 B |
|
Before Width: | Height: | Size: 153 B |
|
Before Width: | Height: | Size: 150 B |
|
Before Width: | Height: | Size: 419 B |
|
Before Width: | Height: | Size: 152 B |
@ -1,11 +0,0 @@
|
|||||||
<svg
|
|
||||||
id="mask"
|
|
||||||
viewbox="0 0 16 16"
|
|
||||||
preserveAspectRatio="xMinYMin meet"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<path d="M7.9 7.9l2.1 7.5 1.7-2.6 3.2 3.2 1.1-1.1-3.3-3.2 2.7-1.6z">
|
|
||||||
</path>
|
|
||||||
<path d="M8 12h-7v-9h12v5.4l1 0.2v-6.6h-14v11h8.2z">
|
|
||||||
</path>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 313 B |
|
Before Width: | Height: | Size: 176 B |
|
Before Width: | Height: | Size: 162 B |
|
Before Width: | Height: | Size: 296 B |
|
Before Width: | Height: | Size: 246 B |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 858 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 193 B |
|
Before Width: | Height: | Size: 350 B |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 103 B |
|
Before Width: | Height: | Size: 139 B |
|
Before Width: | Height: | Size: 220 B |
|
Before Width: | Height: | Size: 210 B |
|
Before Width: | Height: | Size: 510 B |
|
Before Width: | Height: | Size: 182 B |
|
Before Width: | Height: | Size: 661 B |
|
Before Width: | Height: | Size: 369 B |
|
Before Width: | Height: | Size: 159 B |
|
Before Width: | Height: | Size: 240 B |
|
Before Width: | Height: | Size: 404 B |
|
Before Width: | Height: | Size: 302 B |
|
Before Width: | Height: | Size: 194 B |
|
Before Width: | Height: | Size: 514 B |
|
Before Width: | Height: | Size: 366 B |
|
Before Width: | Height: | Size: 247 B |
|
Before Width: | Height: | Size: 439 B |
|
Before Width: | Height: | Size: 343 B |
|
Before Width: | Height: | Size: 326 B |
|
Before Width: | Height: | Size: 298 B |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 511 B |
|
Before Width: | Height: | Size: 232 B |
|
Before Width: | Height: | Size: 730 B |
|
Before Width: | Height: | Size: 467 B |
|
Before Width: | Height: | Size: 203 B |
|
Before Width: | Height: | Size: 142 B |
|
Before Width: | Height: | Size: 448 B |
|
Before Width: | Height: | Size: 220 B |
|
Before Width: | Height: | Size: 820 B |
|
Before Width: | Height: | Size: 283 B |
|
Before Width: | Height: | Size: 256 B |
|
Before Width: | Height: | Size: 469 B |
|
Before Width: | Height: | Size: 212 B |
|
Before Width: | Height: | Size: 273 B |
|
Before Width: | Height: | Size: 135 B |
|
Before Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 309 B |
|
Before Width: | Height: | Size: 490 B |
|
Before Width: | Height: | Size: 194 B |
|
Before Width: | Height: | Size: 450 B |
|
Before Width: | Height: | Size: 200 B |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 925 B |
|
Before Width: | Height: | Size: 367 B |
|
Before Width: | Height: | Size: 540 B |
|
Before Width: | Height: | Size: 219 B |
|
Before Width: | Height: | Size: 166 B |
|
Before Width: | Height: | Size: 330 B |
|
Before Width: | Height: | Size: 908 B |