[0] | 1 | <?php |
---|
[3731] | 2 | /** |
---|
| 3 | * @brief pages, a plugin for Dotclear 2 |
---|
| 4 | * |
---|
| 5 | * @package Dotclear |
---|
| 6 | * @subpackage Plugins |
---|
| 7 | * |
---|
| 8 | * @copyright Olivier Meunier & Association Dotclear |
---|
| 9 | * @copyright GPL-2.0-only |
---|
| 10 | */ |
---|
| 11 | |
---|
[3730] | 12 | if (!defined('DC_RC_PATH')) {return;} |
---|
[0] | 13 | |
---|
[3730] | 14 | $core->addBehavior('coreBlogBeforeGetPosts', array('publicPages', 'coreBlogBeforeGetPosts')); |
---|
[3042] | 15 | |
---|
[0] | 16 | # Localized string we find in template |
---|
| 17 | __('Published on'); |
---|
| 18 | __('This page\'s comments feed'); |
---|
| 19 | |
---|
[3730] | 20 | require dirname(__FILE__) . '/_widgets.php'; |
---|
[0] | 21 | |
---|
[3042] | 22 | class publicPages |
---|
| 23 | { |
---|
[3730] | 24 | public static function coreBlogBeforeGetPosts($params) |
---|
| 25 | { |
---|
| 26 | global $core; |
---|
[3042] | 27 | |
---|
[3730] | 28 | if ($core->url->type == 'search') { |
---|
| 29 | // Add page post type for searching |
---|
| 30 | if (isset($params['post_type'])) { |
---|
| 31 | if (!is_array($params['post_type'])) { |
---|
| 32 | // Convert it in array |
---|
| 33 | $params['post_type'] = array($params['post_type']); |
---|
| 34 | } |
---|
| 35 | if (!in_array('page', $params['post_type'])) { |
---|
| 36 | // Add page post type |
---|
| 37 | $params['post_type'][] = 'page'; |
---|
| 38 | } |
---|
| 39 | } else { |
---|
| 40 | // Dont miss default post type (aka post) |
---|
| 41 | $params['post_type'] = array('post', 'page'); |
---|
| 42 | } |
---|
| 43 | } |
---|
| 44 | } |
---|
[3042] | 45 | } |
---|
| 46 | |
---|
[0] | 47 | class urlPages extends dcUrlHandlers |
---|
| 48 | { |
---|
[3730] | 49 | public static function pages($args) |
---|
| 50 | { |
---|
| 51 | if ($args == '') { |
---|
| 52 | # No page was specified. |
---|
| 53 | self::p404(); |
---|
| 54 | } else { |
---|
| 55 | $_ctx = &$GLOBALS['_ctx']; |
---|
| 56 | $core = &$GLOBALS['core']; |
---|
[2566] | 57 | |
---|
[3730] | 58 | $core->blog->withoutPassword(false); |
---|
[2566] | 59 | |
---|
[3730] | 60 | $params = new ArrayObject(array( |
---|
| 61 | 'post_type' => 'page', |
---|
| 62 | 'post_url' => $args)); |
---|
[2566] | 63 | |
---|
[3730] | 64 | $core->callBehavior('publicPagesBeforeGetPosts', $params, $args); |
---|
[2566] | 65 | |
---|
[3730] | 66 | $_ctx->posts = $core->blog->getPosts($params); |
---|
[2566] | 67 | |
---|
[3730] | 68 | $_ctx->comment_preview = new ArrayObject(); |
---|
| 69 | $_ctx->comment_preview['content'] = ''; |
---|
| 70 | $_ctx->comment_preview['rawcontent'] = ''; |
---|
| 71 | $_ctx->comment_preview['name'] = ''; |
---|
| 72 | $_ctx->comment_preview['mail'] = ''; |
---|
| 73 | $_ctx->comment_preview['site'] = ''; |
---|
| 74 | $_ctx->comment_preview['preview'] = false; |
---|
| 75 | $_ctx->comment_preview['remember'] = false; |
---|
[2566] | 76 | |
---|
[3730] | 77 | $core->blog->withoutPassword(true); |
---|
[2566] | 78 | |
---|
[3730] | 79 | if ($_ctx->posts->isEmpty()) { |
---|
| 80 | # The specified page does not exist. |
---|
| 81 | self::p404(); |
---|
| 82 | } else { |
---|
| 83 | $post_id = $_ctx->posts->post_id; |
---|
| 84 | $post_password = $_ctx->posts->post_password; |
---|
[2566] | 85 | |
---|
[3730] | 86 | # Password protected entry |
---|
| 87 | if ($post_password != '' && !$_ctx->preview) { |
---|
| 88 | # Get passwords cookie |
---|
| 89 | if (isset($_COOKIE['dc_passwd'])) { |
---|
| 90 | $pwd_cookie = json_decode($_COOKIE['dc_passwd']); |
---|
| 91 | if ($pwd_cookie === null) { |
---|
| 92 | $pwd_cookie = array(); |
---|
| 93 | } else { |
---|
| 94 | $pwd_cookie = (array) $pwd_cookie; |
---|
| 95 | } |
---|
| 96 | } else { |
---|
| 97 | $pwd_cookie = array(); |
---|
| 98 | } |
---|
[2566] | 99 | |
---|
[3730] | 100 | # Check for match |
---|
| 101 | # Note: We must prefix post_id key with '#'' in pwd_cookie array in order to avoid integer conversion |
---|
| 102 | # because MyArray["12345"] is treated as MyArray[12345] |
---|
| 103 | if ((!empty($_POST['password']) && $_POST['password'] == $post_password) |
---|
| 104 | || (isset($pwd_cookie['#' . $post_id]) && $pwd_cookie['#' . $post_id] == $post_password)) { |
---|
| 105 | $pwd_cookie['#' . $post_id] = $post_password; |
---|
| 106 | setcookie('dc_passwd', json_encode($pwd_cookie), 0, '/'); |
---|
| 107 | } else { |
---|
| 108 | self::serveDocument('password-form.html', 'text/html', false); |
---|
| 109 | return; |
---|
| 110 | } |
---|
| 111 | } |
---|
[2566] | 112 | |
---|
[3730] | 113 | $post_comment = |
---|
| 114 | isset($_POST['c_name']) && isset($_POST['c_mail']) && |
---|
| 115 | isset($_POST['c_site']) && isset($_POST['c_content']) && |
---|
| 116 | $_ctx->posts->commentsActive(); |
---|
[2566] | 117 | |
---|
[3730] | 118 | # Posting a comment |
---|
| 119 | if ($post_comment) { |
---|
| 120 | # Spam trap |
---|
| 121 | if (!empty($_POST['f_mail'])) { |
---|
| 122 | http::head(412, 'Precondition Failed'); |
---|
| 123 | header('Content-Type: text/plain'); |
---|
| 124 | echo "So Long, and Thanks For All the Fish"; |
---|
| 125 | # Exits immediately the application to preserve the server. |
---|
| 126 | exit; |
---|
| 127 | } |
---|
[2566] | 128 | |
---|
[3730] | 129 | $name = $_POST['c_name']; |
---|
| 130 | $mail = $_POST['c_mail']; |
---|
| 131 | $site = $_POST['c_site']; |
---|
| 132 | $content = $_POST['c_content']; |
---|
| 133 | $preview = !empty($_POST['preview']); |
---|
[2566] | 134 | |
---|
[3730] | 135 | if ($content != '') { |
---|
| 136 | # --BEHAVIOR-- publicBeforeCommentTransform |
---|
| 137 | $buffer = $core->callBehavior('publicBeforeCommentTransform', $content); |
---|
| 138 | if ($buffer != '') { |
---|
| 139 | $content = $buffer; |
---|
| 140 | } else { |
---|
| 141 | if ($core->blog->settings->system->wiki_comments) { |
---|
| 142 | $core->initWikiComment(); |
---|
| 143 | } else { |
---|
| 144 | $core->initWikiSimpleComment(); |
---|
| 145 | } |
---|
| 146 | $content = $core->wikiTransform($content); |
---|
| 147 | } |
---|
| 148 | $content = $core->HTMLfilter($content); |
---|
| 149 | } |
---|
[2566] | 150 | |
---|
[3730] | 151 | $_ctx->comment_preview['content'] = $content; |
---|
| 152 | $_ctx->comment_preview['rawcontent'] = $_POST['c_content']; |
---|
| 153 | $_ctx->comment_preview['name'] = $name; |
---|
| 154 | $_ctx->comment_preview['mail'] = $mail; |
---|
| 155 | $_ctx->comment_preview['site'] = $site; |
---|
[2566] | 156 | |
---|
[3730] | 157 | if ($preview) { |
---|
| 158 | # --BEHAVIOR-- publicBeforeCommentPreview |
---|
| 159 | $core->callBehavior('publicBeforeCommentPreview', $_ctx->comment_preview); |
---|
[2566] | 160 | |
---|
[3730] | 161 | $_ctx->comment_preview['preview'] = true; |
---|
| 162 | } else { |
---|
| 163 | # Post the comment |
---|
| 164 | $cur = $core->con->openCursor($core->prefix . 'comment'); |
---|
| 165 | $cur->comment_author = $name; |
---|
| 166 | $cur->comment_site = html::clean($site); |
---|
| 167 | $cur->comment_email = html::clean($mail); |
---|
| 168 | $cur->comment_content = $content; |
---|
| 169 | $cur->post_id = $_ctx->posts->post_id; |
---|
| 170 | $cur->comment_status = $core->blog->settings->system->comments_pub ? 1 : -1; |
---|
| 171 | $cur->comment_ip = http::realIP(); |
---|
[2566] | 172 | |
---|
[3730] | 173 | $redir = $_ctx->posts->getURL(); |
---|
| 174 | $redir .= $core->blog->settings->system->url_scan == 'query_string' ? '&' : '?'; |
---|
[2566] | 175 | |
---|
[3730] | 176 | try |
---|
| 177 | { |
---|
| 178 | if (!text::isEmail($cur->comment_email)) { |
---|
| 179 | throw new Exception(__('You must provide a valid email address.')); |
---|
| 180 | } |
---|
[2566] | 181 | |
---|
[3730] | 182 | # --BEHAVIOR-- publicBeforeCommentCreate |
---|
| 183 | $core->callBehavior('publicBeforeCommentCreate', $cur); |
---|
| 184 | if ($cur->post_id) { |
---|
| 185 | $comment_id = $core->blog->addComment($cur); |
---|
[2566] | 186 | |
---|
[3730] | 187 | # --BEHAVIOR-- publicAfterCommentCreate |
---|
| 188 | $core->callBehavior('publicAfterCommentCreate', $cur, $comment_id); |
---|
| 189 | } |
---|
[2566] | 190 | |
---|
[3730] | 191 | if ($cur->comment_status == 1) { |
---|
| 192 | $redir_arg = 'pub=1'; |
---|
| 193 | } else { |
---|
| 194 | $redir_arg = 'pub=0'; |
---|
| 195 | } |
---|
[2566] | 196 | |
---|
[3730] | 197 | header('Location: ' . $redir . $redir_arg); |
---|
| 198 | } catch (Exception $e) { |
---|
| 199 | $_ctx->form_error = $e->getMessage(); |
---|
| 200 | $_ctx->form_error; |
---|
| 201 | } |
---|
| 202 | } |
---|
| 203 | } |
---|
[2566] | 204 | |
---|
[3730] | 205 | # The entry |
---|
| 206 | if ($_ctx->posts->trackbacksActive()) { |
---|
| 207 | header('X-Pingback: ' . $core->blog->url . $core->url->getURLFor("xmlrpc", $core->blog->id)); |
---|
| 208 | } |
---|
[2566] | 209 | |
---|
[3730] | 210 | $tplset = $core->themes->moduleInfo($core->blog->settings->system->theme, 'tplset'); |
---|
| 211 | if (!empty($tplset) && is_dir(dirname(__FILE__) . '/default-templates/' . $tplset)) { |
---|
| 212 | $core->tpl->setPath($core->tpl->getPath(), dirname(__FILE__) . '/default-templates/' . $tplset); |
---|
| 213 | } else { |
---|
| 214 | $core->tpl->setPath($core->tpl->getPath(), dirname(__FILE__) . '/default-templates/' . DC_DEFAULT_TPLSET); |
---|
| 215 | } |
---|
| 216 | self::serveDocument('page.html'); |
---|
| 217 | } |
---|
| 218 | } |
---|
| 219 | } |
---|
[2603] | 220 | |
---|
[3730] | 221 | public static function pagespreview($args) |
---|
| 222 | { |
---|
| 223 | $core = $GLOBALS['core']; |
---|
| 224 | $_ctx = $GLOBALS['_ctx']; |
---|
[2566] | 225 | |
---|
[3730] | 226 | if (!preg_match('#^(.+?)/([0-9a-z]{40})/(.+?)$#', $args, $m)) { |
---|
| 227 | # The specified Preview URL is malformed. |
---|
| 228 | self::p404(); |
---|
| 229 | } else { |
---|
| 230 | $user_id = $m[1]; |
---|
| 231 | $user_key = $m[2]; |
---|
| 232 | $post_url = $m[3]; |
---|
| 233 | if (!$core->auth->checkUser($user_id, null, $user_key)) { |
---|
| 234 | # The user has no access to the entry. |
---|
| 235 | self::p404(); |
---|
| 236 | } else { |
---|
| 237 | $_ctx->preview = true; |
---|
| 238 | if (defined("DC_ADMIN_URL")) { |
---|
| 239 | $_ctx->xframeoption = DC_ADMIN_URL; |
---|
| 240 | } |
---|
[2566] | 241 | |
---|
[3730] | 242 | self::pages($post_url); |
---|
| 243 | } |
---|
| 244 | } |
---|
| 245 | } |
---|
[0] | 246 | } |
---|
| 247 | |
---|
| 248 | class tplPages |
---|
| 249 | { |
---|
[3730] | 250 | # Widget function |
---|
| 251 | public static function pagesWidget($w) |
---|
| 252 | { |
---|
| 253 | global $core, $_ctx; |
---|
[2566] | 254 | |
---|
[3730] | 255 | if ($w->offline) { |
---|
| 256 | return; |
---|
| 257 | } |
---|
[2778] | 258 | |
---|
[3730] | 259 | if (($w->homeonly == 1 && $core->url->type != 'default') || |
---|
| 260 | ($w->homeonly == 2 && $core->url->type == 'default')) { |
---|
| 261 | return; |
---|
| 262 | } |
---|
[2566] | 263 | |
---|
[3730] | 264 | $params['post_type'] = 'page'; |
---|
| 265 | $params['limit'] = abs((integer) $w->limit); |
---|
| 266 | $params['no_content'] = true; |
---|
| 267 | $params['post_selected'] = false; |
---|
[2566] | 268 | |
---|
[3730] | 269 | $sort = $w->sortby; |
---|
| 270 | if (!in_array($sort, array('post_title', 'post_position', 'post_dt'))) { |
---|
| 271 | $sort = 'post_title'; |
---|
| 272 | } |
---|
[2566] | 273 | |
---|
[3730] | 274 | $order = $w->orderby; |
---|
| 275 | if ($order != 'asc') { |
---|
| 276 | $order = 'desc'; |
---|
| 277 | } |
---|
| 278 | $params['order'] = $sort . ' ' . $order; |
---|
[2566] | 279 | |
---|
[3730] | 280 | $rs = $core->blog->getPosts($params); |
---|
[2566] | 281 | |
---|
[3730] | 282 | if ($rs->isEmpty()) { |
---|
| 283 | return; |
---|
| 284 | } |
---|
[2566] | 285 | |
---|
[3730] | 286 | $res = ($w->title ? $w->renderTitle(html::escapeHTML($w->title)) : '') . '<ul>'; |
---|
[2566] | 287 | |
---|
[3730] | 288 | while ($rs->fetch()) { |
---|
| 289 | $class = ''; |
---|
| 290 | if (($core->url->type == 'pages' && $_ctx->posts instanceof record && $_ctx->posts->post_id == $rs->post_id)) { |
---|
| 291 | $class = ' class="page-current"'; |
---|
| 292 | } |
---|
| 293 | $res .= '<li' . $class . '><a href="' . $rs->getURL() . '">' . |
---|
| 294 | html::escapeHTML($rs->post_title) . '</a></li>'; |
---|
| 295 | } |
---|
[2566] | 296 | |
---|
[3730] | 297 | $res .= '</ul>'; |
---|
[2566] | 298 | |
---|
[3730] | 299 | return $w->renderDiv($w->content_only, 'pages ' . $w->class, '', $res); |
---|
| 300 | } |
---|
[0] | 301 | } |
---|