00001 <?php
00007 namespace Habari;
00008
00014 class AdminPostsHandler extends AdminHandler
00015 {
00019 public function get_publish( $template = 'publish' )
00020 {
00021 $extract = $this->handler_vars->filter_keys( 'id', 'content_type_name' );
00022 foreach ( $extract as $key => $value ) {
00023 $$key = $value;
00024 }
00025 $content_type = Post::type($content_type_name);
00026
00027
00028 if ( isset( $id ) && ( $id != 0 ) ) {
00029 $post = Post::get( array( 'id' => $id, 'status' => Post::status( 'any' ) ) );
00030 Plugins::act('admin_publish_post', $post);
00031 if ( !$post ) {
00032 Session::error( _t( "You don't have permission to edit that post" ) );
00033 $this->get_blank();
00034 }
00035 if ( ! ACL::access_check( $post->get_access(), 'edit' ) ) {
00036 Session::error( _t( "You don't have permission to edit that post" ) );
00037 $this->get_blank();
00038 }
00039 $this->theme->post = $post;
00040 }
00041 else {
00042 $post = new Post();
00043 Plugins::act('admin_publish_post', $post);
00044 $this->theme->post = $post;
00045 $post->content_type = Post::type( ( isset( $content_type ) ) ? $content_type : 'entry' );
00046
00047
00048 $user = User::identify();
00049 $type = 'post_' . Post::type_name( $post->content_type );
00050 if ( ACL::user_cannot( $user, $type ) || ( ! ACL::user_can( $user, 'post_any', 'create' ) && ! ACL::user_can( $user, $type, 'create' ) ) ) {
00051 Session::error( _t( 'Access to create posts of type %s is denied', array( Post::type_name( $post->content_type ) ) ) );
00052 $this->get_blank();
00053 }
00054 }
00055
00056 $this->theme->admin_page = _t( 'Publish %s', array( Plugins::filter( 'post_type_display', Post::type_name( $post->content_type ), 'singular' ) ) );
00057 $this->theme->admin_title = _t( 'Publish %s', array( Plugins::filter( 'post_type_display', Post::type_name( $post->content_type ), 'singular' ) ) );
00058
00059 $statuses = Post::list_post_statuses( false );
00060 $this->theme->statuses = $statuses;
00061
00062 $form = $post->get_form( 'admin' );
00063
00064 $this->theme->form = $form;
00065
00066 $this->theme->wsse = Utils::WSSE();
00067 $this->display( $template );
00068 }
00069
00073 public function post_publish()
00074 {
00075 $this->get_publish();
00076 }
00077
00082 private function fetch_posts( $params = array() )
00083 {
00084
00085
00086 $locals = array(
00087 'do_update' => false,
00088 'post_ids' => null,
00089 'nonce' => '',
00090 'timestamp' => '',
00091 'password_digest' => '',
00092 'change' => '',
00093 'user_id' => null,
00094 'type' => null,
00095 'status' => null,
00096 'limit' => null,
00097 'offset' => null,
00098 'search' => '',
00099 );
00100 foreach ( $locals as $varname => $default ) {
00101 $$varname = isset( $this->handler_vars[$varname] ) ? $this->handler_vars[$varname] : ( isset( $params[$varname] ) ? $params[$varname] : $default );
00102 }
00103
00104
00105
00106
00107 if ( isset( $this->handler_vars['type'] ) ) {
00108 $type = (int) $this->handler_vars['type'];
00109 }
00110 if ( isset( $this->handler_vars['status'] ) ) {
00111 $status = (int) $this->handler_vars['status'];
00112 }
00113
00114
00115 if ( $do_update && isset( $post_ids ) ) {
00116 $okay = true;
00117 if ( empty( $nonce ) || empty( $timestamp ) || empty( $password_digest ) ) {
00118 $okay = false;
00119 }
00120 $wsse = Utils::WSSE( $nonce, $timestamp );
00121 if ( $password_digest != $wsse['digest'] ) {
00122 $okay = false;
00123 }
00124 if ( $okay ) {
00125 foreach ( $post_ids as $id ) {
00126 $ids[] = array( 'id' => $id );
00127 }
00128 $to_update = Posts::get( array( 'where' => $ids, 'nolimit' => 1 ) );
00129 foreach ( $to_update as $post ) {
00130 switch ( $change ) {
00131 case 'delete':
00132 if ( ACL::access_check( $post->get_access(), 'delete' ) ) {
00133 $post->delete();
00134 }
00135 break;
00136 case 'publish':
00137 if ( ACL::access_check( $post->get_access(), 'edit' ) ) {
00138 $post->publish();
00139 }
00140 break;
00141 case 'unpublish':
00142 if ( ACL::access_check( $post->get_access(), 'edit' ) ) {
00143 $post->status = Post::status( 'draft' );
00144 $post->update();
00145 }
00146 break;
00147 }
00148 }
00149 unset( $this->handler_vars['change'] );
00150 }
00151 }
00152
00153
00154
00155
00156 $this->theme->wsse = Utils::WSSE();
00157
00158
00159 $user_filters = array();
00160 if ( isset( $type ) ) {
00161 $user_filters['content_type'] = $type;
00162 }
00163 if ( isset( $status ) ) {
00164 $user_filters['status'] = $status;
00165 }
00166 if ( isset( $limit ) ) {
00167 $user_filters['limit'] = $limit;
00168 }
00169 if ( isset( $offset ) ) {
00170 $user_filters['offset'] = $offset;
00171 }
00172 if ( isset( $user_id ) ) {
00173 $user_filters['user_id'] = $user_id;
00174 }
00175
00176 if ( '' != $search ) {
00177 $user_filters = array_merge( $user_filters, Posts::search_to_get( $search ) );
00178 }
00179 $this->theme->posts = Posts::get( array_merge( array( 'preset' => 'admin' ), $user_filters ) );
00180
00181
00182 $this->theme->search_args = '';
00183 if ( $status != Post::status( 'any' ) ) {
00184 $this->theme->search_args = 'status:' . Post::status_name( $status ) . ' ';
00185 }
00186 if ( $type != Post::type( 'any' ) ) {
00187 $this->theme->search_args .= 'type:' . Post::type_name( $type ) . ' ';
00188 }
00189 if ( $user_id != 0 ) {
00190 $this->theme->search_args .= 'author:' . User::get_by_id( $user_id )->username .' ';
00191 }
00192 if ( $search != '' ) {
00193 $this->theme->search_args .= $search;
00194 }
00195
00196 $monthcts = Posts::get( array_merge( $user_filters, array( 'month_cts' => true, 'nolimit' => true ) ) );
00197 $years = array();
00198 foreach ( $monthcts as $month ) {
00199 if ( isset( $years[$month->year] ) ) {
00200 $years[$month->year][] = $month;
00201 }
00202 else {
00203 $years[$month->year] = array( $month );
00204 }
00205 }
00206
00207 $this->theme->years = $years;
00208
00209 }
00210
00215 public function get_posts()
00216 {
00217 $this->post_posts();
00218 }
00219
00224 public function post_posts()
00225 {
00226 $this->fetch_posts();
00227
00228 $statuses = array_keys( Post::list_post_statuses() );
00229 array_shift( $statuses );
00230 $labels = array_map(
00231 function($a) {return MultiByte::ucfirst(Plugins::filter("post_status_display", $a));},
00232 $statuses
00233 );
00234 $terms = array_map(
00235 function($a) {return "status:{$a}";},
00236 $statuses
00237 );
00238 $statuses = array_combine( $terms, $labels );
00239
00240
00241 $types = array_keys( Post::list_active_post_types() );
00242 array_shift( $types );
00243 $labels = array_map(
00244 function($a) {return Plugins::filter("post_type_display", $a, "singular");},
00245 $types
00246 );
00247 $terms = array_map(
00248 function($a) {return "type:{$a}";},
00249 $types
00250 );
00251 $types = array_combine( $terms, $labels );
00252
00253 $special_searches = array_merge( $statuses, $types );
00254
00255 $special_searches["author:" . User::identify()->username] = _t( 'My Posts' );
00256
00257 $this->theme->admin_page = _t( 'Manage Posts' );
00258 $this->theme->admin_title = _t( 'Manage Posts' );
00259 $this->theme->special_searches = Plugins::filter( 'special_searches', $special_searches );
00260
00261 Stack::add('admin_header_javascript', 'visualsearch' );
00262 Stack::add('admin_stylesheet', 'visualsearch-css');
00263 Stack::add('admin_stylesheet', 'visualsearch-datauri-css');
00264
00265 $this->display( 'posts' );
00266 }
00267
00271 public function ajax_media( $handler_vars )
00272 {
00273 Utils::check_request_method( array( 'POST' ) );
00274
00275 $path = $handler_vars['path'];
00276 $rpath = $path;
00277 $silo = Media::get_silo( $rpath, true );
00278 $assets = Media::dir( $path );
00279 $output = array(
00280 'ok' => 1,
00281 'dirs' => array(),
00282 'files' => array(),
00283 'path' => $path,
00284 );
00285 foreach ( $assets as $asset ) {
00286 if ( $asset->is_dir ) {
00287 $output['dirs'][$asset->basename] = $asset->get_props();
00288 }
00289 else {
00290 $output['files'][$asset->basename] = $asset->get_props();
00291 }
00292 }
00293 $rootpath = MultiByte::strpos( $path, '/' ) !== false ? MultiByte::substr( $path, 0, MultiByte::strpos( $path, '/' ) ) : $path;
00294 $controls = array( 'root' => '<a href="#" onclick="habari.media.fullReload();habari.media.showdir(\''. $rootpath . '\');return false;">' . _t( 'Root' ) . '</a>' );
00295 $controls = Plugins::filter( 'media_controls', $controls, $silo, $rpath, '' );
00296 $controls_out = '';
00297 foreach ( $controls as $k => $v ) {
00298 if ( is_numeric( $k ) ) {
00299 $controls_out .= "<li>{$v}</li>";
00300 }
00301 else {
00302 $controls_out .= "<li class=\"{$k}\">{$v}</li>";
00303 }
00304 }
00305 $output['controls'] = $controls_out;
00306
00307 $ar = new AjaxResponse();
00308 $ar->data = $output;
00309 $ar->out();
00310 }
00311
00315 public function ajax_media_panel( $handler_vars )
00316 {
00317 Utils::check_request_method( array( 'POST' ) );
00318
00319 $path = $handler_vars['path'];
00320 $panelname = $handler_vars['panel'];
00321 $rpath = $path;
00322 $silo = Media::get_silo( $rpath, true );
00323
00324 $panel = '';
00325 $panel = Plugins::filter( 'media_panels', $panel, $silo, $rpath, $panelname );
00326
00327 $controls = array();
00328 $controls = Plugins::filter( 'media_controls', $controls, $silo, $rpath, $panelname );
00329 $controls_out = '';
00330 foreach ( $controls as $k => $v ) {
00331 if ( is_numeric( $k ) ) {
00332 $controls_out .= "<li>{$v}</li>";
00333 }
00334 else {
00335 $controls_out .= "<li class=\"{$k}\">{$v}</li>";
00336 }
00337 }
00338 $output = array(
00339 'controls' => $controls_out,
00340 'panel' => $panel,
00341 );
00342
00343 $ar = new AjaxResponse();
00344 $ar->data = $output;
00345 $ar->out();
00346 }
00347
00351 public function ajax_media_upload( $handler_vars )
00352 {
00353 Utils::check_request_method( array( 'POST' ) );
00354
00355 $path = $handler_vars['path'];
00356 $panelname = $handler_vars['panel'];
00357 $rpath = $path;
00358 $silo = Media::get_silo( $rpath, true );
00359
00360 $panel = '';
00361 $panel = Plugins::filter( 'media_panels', $panel, $silo, $rpath, $panelname );
00362
00363 $controls = array();
00364 $controls = Plugins::filter( 'media_controls', $controls, $silo, $rpath, $panelname );
00365 $controls_out = '';
00366 foreach ( $controls as $k => $v ) {
00367 if ( is_numeric( $k ) ) {
00368 $controls_out .= "<li>{$v}</li>";
00369 }
00370 else {
00371 $controls_out .= "<li class=\"{$k}\">{$v}</li>";
00372 }
00373 }
00374 $output = array(
00375 'controls' => $controls_out,
00376 'panel' => $panel,
00377 );
00378
00379 $ar = new AjaxResponse();
00380 $ar->data = $output;
00381 $ar->out( true );
00382 }
00383
00384
00388 public function ajax_posts()
00389 {
00390 Utils::check_request_method( array( 'GET', 'HEAD' ) );
00391
00392 $this->create_theme();
00393
00394 $params = $_GET;
00395
00396 $this->fetch_posts( $params );
00397 $items = $this->theme->fetch( 'posts_items' );
00398 $timeline = $this->theme->fetch( 'timeline_items' );
00399
00400 $item_ids = array();
00401
00402 foreach ( $this->theme->posts as $post ) {
00403 if ( ACL::access_check( $post->get_access(), 'delete' ) ) {
00404 $item_ids['p' . $post->id] = 1;
00405 }
00406 }
00407
00408 $ar = new AjaxResponse();
00409 $ar->data = array(
00410 'items' => $items,
00411 'item_ids' => $item_ids,
00412 'timeline' => $timeline,
00413 );
00414 $ar->out();
00415 }
00416
00421 public function ajax_update_posts( $handler_vars )
00422 {
00423 Utils::check_request_method( array( 'POST' ) );
00424 $response = new AjaxResponse();
00425
00426 $wsse = Utils::WSSE( $handler_vars['nonce'], $handler_vars['timestamp'] );
00427 if ( $handler_vars['digest'] != $wsse['digest'] ) {
00428 $response->message = _t( 'WSSE authentication failed.' );
00429 $response->out();
00430 return;
00431 }
00432
00433 $ids = array();
00434 foreach ( $_POST as $id => $delete ) {
00435
00436 if ( preg_match( '/^p\d+$/', $id ) && $delete ) {
00437 $ids[] = (int) substr( $id, 1 );
00438 }
00439 }
00440 if ( count( $ids ) == 0 ) {
00441 $posts = new Posts();
00442 }
00443 else {
00444 $posts = Posts::get( array( 'id' => $ids, 'nolimit' => true ) );
00445 }
00446
00447 Plugins::act( 'admin_update_posts', $handler_vars['action'], $posts, $this );
00448 $status_msg = _t( 'Unknown action "%s"', array( $handler_vars['action'] ) );
00449 switch ( $handler_vars['action'] ) {
00450 case 'delete':
00451 $deleted = 0;
00452 foreach ( $posts as $post ) {
00453 if ( ACL::access_check( $post->get_access(), 'delete' ) ) {
00454 $post->delete();
00455 $deleted++;
00456 }
00457 }
00458 if ( $deleted != count( $posts ) ) {
00459 $response->message = _t( 'You did not have permission to delete some posts.' );
00460 }
00461 else {
00462 $response->message = sprintf( _n( 'Deleted %d post', 'Deleted %d posts', count( $ids ) ), count( $ids ) );
00463 }
00464 break;
00465 default:
00466
00467 Plugins::act( 'admin_posts_action', $response, $handler_vars['action'], $posts );
00468 break;
00469 }
00470
00471 $response->out();
00472 exit;
00473 }
00474 }