| 1 | <?php |
|---|
| 2 | # -- BEGIN LICENSE BLOCK ---------------------------------- |
|---|
| 3 | # This file is part of dcRevisions, a plugin for Dotclear. |
|---|
| 4 | # |
|---|
| 5 | # Copyright (c) 2010 Tomtom and contributors |
|---|
| 6 | # http://blog.zenstyle.fr/ |
|---|
| 7 | # |
|---|
| 8 | # Licensed under the GPL version 2.0 license. |
|---|
| 9 | # A copy of this license is available in LICENSE file or at |
|---|
| 10 | # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
|---|
| 11 | # -- END LICENSE BLOCK ------------------------------------ |
|---|
| 12 | |
|---|
| 13 | class dcRevisions |
|---|
| 14 | { |
|---|
| 15 | public function __construct($core) |
|---|
| 16 | { |
|---|
| 17 | $this->core = $core; |
|---|
| 18 | } |
|---|
| 19 | |
|---|
| 20 | public function getRevisions($params,$count_only = false) |
|---|
| 21 | { |
|---|
| 22 | if ($count_only) { |
|---|
| 23 | $f = 'COUNT(revision_id)'; |
|---|
| 24 | } |
|---|
| 25 | else { |
|---|
| 26 | $f = 'R.revision_id, R.post_id, R.user_id, R.revision_type, '. |
|---|
| 27 | 'R.revision_dt, R.revision_tz, R.revision_excerpt_diff, '. |
|---|
| 28 | 'R.revision_excerpt_xhtml_diff, R.revision_content_diff, '. |
|---|
| 29 | 'R.revision_content_xhtml_diff, U.user_url, U.user_name, '. |
|---|
| 30 | 'U.user_firstname, U.user_displayname'; |
|---|
| 31 | } |
|---|
| 32 | |
|---|
| 33 | $strReq = 'SELECT '.$f.' FROM '.$this->core->prefix.'revision R '. |
|---|
| 34 | 'LEFT JOIN '.$this->core->prefix.'user U ON R.user_id = U.user_id '; |
|---|
| 35 | |
|---|
| 36 | if (!empty($params['from'])) { |
|---|
| 37 | $strReq .= $params['from'].' '; |
|---|
| 38 | } |
|---|
| 39 | |
|---|
| 40 | $strReq .= "WHERE R.blog_id = '".$this->core->con->escape($this->core->blog->id)."' "; |
|---|
| 41 | |
|---|
| 42 | if (!empty($params['post_id'])) { |
|---|
| 43 | if (is_array($params['post_id'])) { |
|---|
| 44 | array_walk($params['post_id'],create_function('&$v,$k','if($v!==null){$v=(integer)$v;}')); |
|---|
| 45 | } else { |
|---|
| 46 | $params['post_id'] = array((integer) $params['post_id']); |
|---|
| 47 | } |
|---|
| 48 | $strReq .= 'AND R.post_id '.$this->core->con->in($params['post_id']); |
|---|
| 49 | } |
|---|
| 50 | |
|---|
| 51 | if (!empty($params['revision_id'])) { |
|---|
| 52 | if (is_array($params['revision_id'])) { |
|---|
| 53 | array_walk($params['revision_id'],create_function('&$v,$k','if($v!==null){$v=(integer)$v;}')); |
|---|
| 54 | } else { |
|---|
| 55 | $params['revision_id'] = array((integer) $params['revision_id']); |
|---|
| 56 | } |
|---|
| 57 | $strReq .= 'AND R.revision_id '.$this->core->con->in($params['revision_id']); |
|---|
| 58 | } |
|---|
| 59 | |
|---|
| 60 | if (isset($params['post_type'])) { |
|---|
| 61 | if (is_array($params['post_type']) && !empty($params['post_type'])) { |
|---|
| 62 | $strReq .= 'AND R.revision_type '.$this->core->con->in($params['revision_type']); |
|---|
| 63 | } elseif ($params['post_type'] != '') { |
|---|
| 64 | $strReq .= "AND R.revision_type = '".$this->core->con->escape($params['revision_type'])."' "; |
|---|
| 65 | } |
|---|
| 66 | } |
|---|
| 67 | |
|---|
| 68 | if (!empty($params['sql'])) { |
|---|
| 69 | $strReq .= $params['sql'].' '; |
|---|
| 70 | } |
|---|
| 71 | |
|---|
| 72 | if (!$count_only) { |
|---|
| 73 | if (!empty($params['order'])) { |
|---|
| 74 | $strReq .= 'ORDER BY '.$this->core->con->escape($params['order']).' '; |
|---|
| 75 | } else { |
|---|
| 76 | $strReq .= 'ORDER BY revision_dt DESC '; |
|---|
| 77 | } |
|---|
| 78 | } |
|---|
| 79 | |
|---|
| 80 | if (!$count_only && !empty($params['limit'])) { |
|---|
| 81 | $strReq .= $this->core->con->limit($params['limit']); |
|---|
| 82 | } |
|---|
| 83 | |
|---|
| 84 | $rs = $this->core->con->select($strReq); |
|---|
| 85 | $rs->core = $this->core; |
|---|
| 86 | $rs->extend('dcRevisionsExtensions'); |
|---|
| 87 | |
|---|
| 88 | return $rs; |
|---|
| 89 | } |
|---|
| 90 | |
|---|
| 91 | public function addRevision($pcur,$post_id) |
|---|
| 92 | { |
|---|
| 93 | $rs = $this->core->con->select( |
|---|
| 94 | 'SELECT MAX(revision_id) '. |
|---|
| 95 | 'FROM '.$this->core->prefix.'revision' |
|---|
| 96 | ); |
|---|
| 97 | $revision_id = $rs->f(0) + 1; |
|---|
| 98 | |
|---|
| 99 | $rs = $this->core->blog->getPosts(array('post_id' => $post_id)); |
|---|
| 100 | |
|---|
| 101 | $old = array( |
|---|
| 102 | 'post_excerpt' => $rs->post_excerpt, |
|---|
| 103 | 'post_excerpt_xhtml' => $rs->post_excerpt_xhtml, |
|---|
| 104 | 'post_content' => $rs->post_content, |
|---|
| 105 | 'post_content_xhtml' => $rs->post_content_xhtml |
|---|
| 106 | ); |
|---|
| 107 | $new = array( |
|---|
| 108 | 'post_excerpt' => $pcur->post_excerpt, |
|---|
| 109 | 'post_excerpt_xhtml' => $pcur->post_excerpt_xhtml, |
|---|
| 110 | 'post_content' => $pcur->post_content, |
|---|
| 111 | 'post_content_xhtml' => $pcur->post_content_xhtml |
|---|
| 112 | ); |
|---|
| 113 | |
|---|
| 114 | $diff = $this->getDiff($new,$old); |
|---|
| 115 | |
|---|
| 116 | $insert = false; |
|---|
| 117 | foreach ($diff as $k => $v) { |
|---|
| 118 | if ($v !== '') { |
|---|
| 119 | $insert = true; |
|---|
| 120 | } |
|---|
| 121 | } |
|---|
| 122 | |
|---|
| 123 | if ($insert) { |
|---|
| 124 | $rcur = $this->core->con->openCursor($this->core->prefix.'revision'); |
|---|
| 125 | $rcur->revision_id = $revision_id; |
|---|
| 126 | $rcur->post_id = $post_id; |
|---|
| 127 | $rcur->user_id = $this->core->auth->userID(); |
|---|
| 128 | $rcur->blog_id = $this->core->blog->id; |
|---|
| 129 | $rcur->revision_dt = date('Y-m-d H:i:s'); |
|---|
| 130 | $rcur->revision_tz = $this->core->auth->getInfo('user_tz'); |
|---|
| 131 | $rcur->revision_type = $pcur->post_type; |
|---|
| 132 | $rcur->revision_excerpt_diff = $diff['post_excerpt']; |
|---|
| 133 | $rcur->revision_excerpt_xhtml_diff = $diff['post_excerpt_xhtml']; |
|---|
| 134 | $rcur->revision_content_diff = $diff['post_content']; |
|---|
| 135 | $rcur->revision_content_xhtml_diff = $diff['post_content_xhtml']; |
|---|
| 136 | |
|---|
| 137 | $this->core->con->writeLock($this->core->prefix.'revision'); |
|---|
| 138 | $rcur->insert(); |
|---|
| 139 | $this->core->con->unlock(); |
|---|
| 140 | } |
|---|
| 141 | } |
|---|
| 142 | |
|---|
| 143 | public function getDiff($n,$o) |
|---|
| 144 | { |
|---|
| 145 | $diff = array( |
|---|
| 146 | 'post_excerpt' => '', |
|---|
| 147 | 'post_excerpt_xhtml' => '', |
|---|
| 148 | 'post_content' => '', |
|---|
| 149 | 'post_content_xhtml' => '' |
|---|
| 150 | ); |
|---|
| 151 | |
|---|
| 152 | try { |
|---|
| 153 | foreach ($diff as $k => $v) { |
|---|
| 154 | $diff[$k] = uDiff::diff($n[$k],$o[$k]); |
|---|
| 155 | } |
|---|
| 156 | |
|---|
| 157 | return $diff; |
|---|
| 158 | } |
|---|
| 159 | catch (Exception $e) |
|---|
| 160 | { |
|---|
| 161 | $this->core->error->add($e->getMessage()); |
|---|
| 162 | } |
|---|
| 163 | } |
|---|
| 164 | |
|---|
| 165 | public function setPatch($pid,$rid) |
|---|
| 166 | { |
|---|
| 167 | if (!$this->canPatch($rid)) { |
|---|
| 168 | throw new Exception(__('You are not allowed to patch this entry with this revision')); |
|---|
| 169 | } |
|---|
| 170 | |
|---|
| 171 | try |
|---|
| 172 | { |
|---|
| 173 | $patch = $this->getPatch($pid,$rid); |
|---|
| 174 | |
|---|
| 175 | $p = $this->core->blog->getPosts(array('post_id' => $pid)); |
|---|
| 176 | |
|---|
| 177 | $cur = $this->core->con->openCursor($this->core->prefix.'post'); |
|---|
| 178 | |
|---|
| 179 | $cur->post_title = $p->post_title; |
|---|
| 180 | $cur->cat_id = $p->cat_id ? $p->cat_id : null; |
|---|
| 181 | $cur->post_dt = $p->post_dt ? date('Y-m-d H:i:00',strtotime($p->post_dt)) : ''; |
|---|
| 182 | $cur->post_format = $p->post_format; |
|---|
| 183 | $cur->post_password = $p->post_password; |
|---|
| 184 | $cur->post_lang = $p->post_lang; |
|---|
| 185 | $cur->post_notes = $p->post_notes; |
|---|
| 186 | $cur->post_status = $p->post_status; |
|---|
| 187 | $cur->post_selected = (integer) $p->post_selected; |
|---|
| 188 | $cur->post_open_comment = (integer) $p->post_open_comment; |
|---|
| 189 | $cur->post_open_tb = (integer) $p->post_open_tb; |
|---|
| 190 | |
|---|
| 191 | $cur->post_excerpt = $patch['post_excerpt']; |
|---|
| 192 | $cur->post_excerpt_xhtml = $patch['post_excerpt_xhtml']; |
|---|
| 193 | $cur->post_content = $patch['post_content']; |
|---|
| 194 | $cur->post_content_xhtml = $patch['post_content_xhtml']; |
|---|
| 195 | |
|---|
| 196 | # --BEHAVIOR-- adminBeforePostUpdate |
|---|
| 197 | $this->core->callBehavior('adminBeforePostUpdate',$cur,$pid); |
|---|
| 198 | |
|---|
| 199 | $this->core->auth->sudo(array($this->core->blog,'updPost'),$pid,$cur); |
|---|
| 200 | |
|---|
| 201 | # --BEHAVIOR-- adminAfterPostUpdate |
|---|
| 202 | $this->core->callBehavior('adminAfterPostUpdate',$cur,$pid); |
|---|
| 203 | |
|---|
| 204 | http::redirect('post.php?id='.$pid.'&upd=1'); |
|---|
| 205 | } |
|---|
| 206 | catch (Exception $e) |
|---|
| 207 | { |
|---|
| 208 | $this->core->error->add($e->getMessage()); |
|---|
| 209 | } |
|---|
| 210 | } |
|---|
| 211 | |
|---|
| 212 | public function getPatch($pid,$rid) |
|---|
| 213 | { |
|---|
| 214 | $params = array( |
|---|
| 215 | 'post_id' => $pid |
|---|
| 216 | ); |
|---|
| 217 | |
|---|
| 218 | $p = $this->core->blog->getPosts($params); |
|---|
| 219 | $r = $this->getRevisions($params); |
|---|
| 220 | |
|---|
| 221 | $patch = array( |
|---|
| 222 | 'post_excerpt' => $p->post_excerpt, |
|---|
| 223 | 'post_excerpt_xhtml' => $p->post_excerpt_xhtml, |
|---|
| 224 | 'post_content' => $p->post_content, |
|---|
| 225 | 'post_content_xhtml' => $p->post_content_xhtml |
|---|
| 226 | ); |
|---|
| 227 | |
|---|
| 228 | while ($r->fetch()) { |
|---|
| 229 | foreach ($patch as $k => $v) { |
|---|
| 230 | if ($k === 'post_excerpt') { $f = 'revision_excerpt_diff'; } |
|---|
| 231 | if ($k === 'post_excerpt_xhtml') { $f = 'revision_excerpt_xhtml_diff'; } |
|---|
| 232 | if ($k === 'post_content') { $f = 'revision_content_diff'; } |
|---|
| 233 | if ($k === 'post_content_xhtml') { $f = 'revision_content_xhtml_diff'; } |
|---|
| 234 | |
|---|
| 235 | uDiff::check($r->{$f}); |
|---|
| 236 | $patch[$k] = uDiff::patch($v,$r->{$f}); |
|---|
| 237 | } |
|---|
| 238 | |
|---|
| 239 | if ($r->revision_id === $rid) { |
|---|
| 240 | break; |
|---|
| 241 | } |
|---|
| 242 | } |
|---|
| 243 | |
|---|
| 244 | return $patch; |
|---|
| 245 | } |
|---|
| 246 | |
|---|
| 247 | protected function canPatch($ird) |
|---|
| 248 | { |
|---|
| 249 | $r = $this->getRevisions(array('revision_id' => $rid)); |
|---|
| 250 | |
|---|
| 251 | return ($r->canPatch()); |
|---|
| 252 | } |
|---|
| 253 | } |
|---|
| 254 | |
|---|
| 255 | ?> |
|---|