b2evolution PHP Cross Reference Blogging Systems

Source: /inc/dashboard/model/_dashboard.funcs.php - 481 lines - 17352 bytes - Summary - Text - Print

Description: This file implements the support functions for the dashboard. b2evolution - {@link http://b2evolution.net/} Released under GNU GPL License - {@link http://b2evolution.net/about/license.html}

   1  <?php
   2  /**
   3   * This file implements the support functions for the dashboard.
   4   *
   5   * b2evolution - {@link http://b2evolution.net/}
   6   * Released under GNU GPL License - {@link http://b2evolution.net/about/license.html}
   7   *
   8   * @copyright (c)2003-2014 by Francois Planque - {@link http://fplanque.com/}
   9   *
  10   * {@internal Open Source relicensing agreement:
  11   * }}
  12   *
  13   * @package admin
  14   *
  15   * {@internal Below is a list of authors who have contributed to design/coding of this file: }}
  16   * @author fplanque: Francois PLANQUE.
  17   *
  18   * @version $Id: _dashboard.funcs.php 6136 2014-03-08 07:59:48Z manuel $
  19   */
  20  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
  21  
  22   /**
  23   * Get updates from b2evolution.net
  24   *
  25   * @param boolean useful when trying to upgrade to a release that has just been published (in the last 12 hours)
  26   * @return NULL|boolean True if there have been updates, false on error,
  27   *                      NULL if the user has turned off updates.
  28   */
  29  function b2evonet_get_updates( $force_short_delay = false )
  30  {
  31      global $allow_evo_stats; // Possible values: true, false, 'anonymous'
  32      global $DB, $debug, $evonetsrv_host, $evonetsrv_port, $evonetsrv_uri, $servertimenow, $evo_charset;
  33      global $Messages, $Settings, $baseurl, $instance_name, $app_name, $app_version, $app_date;
  34      global $Debuglog;
  35      global $Timer;
  36  
  37      if( ! isset( $allow_evo_stats ) )
  38      {    // Set default value:
  39          $allow_evo_stats = true; // allow (non-anonymous) stats
  40      }
  41      if( $allow_evo_stats === false )
  42      { // Get outta here:
  43          return NULL;
  44      }
  45  
  46      if( $debug == 2 )
  47      {
  48          $update_every = 8;
  49          $attempt_every = 3;
  50      }
  51      elseif( $force_short_delay )
  52      {
  53          $update_every = 180; // 3 minutes
  54          $attempt_every = 60; // 1 minute
  55      }
  56      else
  57      {
  58          $update_every = 3600*12; // 12 hours
  59          $attempt_every = 3600*4; // 4 hours
  60      }
  61  
  62      // Note: do not put $baseurl in here since it would cause too frequently updates, when you have the same install with different $baseurls.
  63      //           Everytime this method gets called on another baseurl, there's a new check for updates!
  64      $version_id = $instance_name.' '.$app_name.' '.$app_version.' '.$app_date;
  65      // This is the last version we checked against the server:
  66      $last_version_checked =  $Settings->get( 'evonet_last_version_checked' );
  67  
  68      $servertime_last_update = $Settings->get( 'evonet_last_update' );
  69      $servertime_last_attempt = $Settings->get( 'evonet_last_attempt' );
  70  
  71      if( $last_version_checked == $version_id )
  72      {    // Current version has already been checked, don't check too often:
  73  
  74          if( $servertime_last_update > $servertimenow - $update_every )
  75          {    // The previous update was less than 12 hours ago, skip this
  76              // echo 'recent update';
  77              return false;
  78          }
  79  
  80          if( $servertime_last_attempt > $servertimenow - $attempt_every)
  81          {    // The previous update attempt was less than 4 hours ago, skip this
  82              // This is so all b2evo's don't go crazy if the server ever is down
  83              // echo 'recent attempt';
  84              return false;
  85          }
  86      }
  87  
  88      $Timer->resume('evonet: check for updates');
  89      $Debuglog->add( sprintf('Getting updates from %s.', $evonetsrv_host), 'evonet' );
  90      if( $debug )
  91      {
  92          $Messages->add( sprintf(T_('Getting updates from %s.'), $evonetsrv_host), 'note' );
  93      }
  94      $Settings->set( 'evonet_last_attempt', $servertimenow );
  95      $Settings->dbupdate();
  96  
  97      // Construct XML-RPC client:
  98      load_funcs('xmlrpc/model/_xmlrpc.funcs.php');
  99      $client = new xmlrpc_client( $evonetsrv_uri, $evonetsrv_host, $evonetsrv_port );
 100      if( $debug > 1 )
 101      {
 102          $client->debug = 1;
 103      }
 104  
 105      // Run system checks:
 106      load_funcs( 'tools/model/_system.funcs.php' );
 107  
 108      // Get system stats to display:
 109      $system_stats = get_system_stats();
 110  
 111      // Construct XML-RPC message:
 112      $message = new xmlrpcmsg(
 113                                  'b2evo.getupdates',                           // Function to be called
 114                                  array(
 115                                      new xmlrpcval( ( $allow_evo_stats === 'anonymous' ? md5( $baseurl ) : $baseurl ), 'string'),    // Unique identifier part 1
 116                                      new xmlrpcval( $instance_name, 'string'),        // Unique identifier part 2
 117                                      new xmlrpcval( $app_name, 'string'),            // Version number
 118                                      new xmlrpcval( $app_version, 'string'),          // Version number
 119                                      new xmlrpcval( $app_date, 'string'),            // Version number
 120                                      new xmlrpcval( array(
 121                                              'this_update' => new xmlrpcval( $servertimenow, 'string' ),
 122                                              'last_update' => new xmlrpcval( $servertime_last_update, 'string' ),
 123                                              'mediadir_status' => new xmlrpcval( $system_stats['mediadir_status'], 'int' ), // If error, then the host is potentially borked
 124                                              'install_removed' => new xmlrpcval( ($system_stats['install_removed'] == 'ok') ? 1 : 0, 'int' ), // How many people do go through this extra measure?
 125                                              'evo_charset' => new xmlrpcval( $system_stats['evo_charset'], 'string' ),            // Do people actually use UTF8?
 126                                              'evo_blog_count' => new xmlrpcval( $system_stats['evo_blog_count'], 'int'),   // How many users do use multiblogging?
 127                                              'cachedir_status' => new xmlrpcval( $system_stats['cachedir_status'], 'int'),
 128                                              'cachedir_size' => new xmlrpcval( $system_stats['cachedir_size'], 'int'),
 129                                              'general_pagecache_enabled' => new xmlrpcval( $system_stats['general_pagecache_enabled'] ? 1 : 0, 'int' ),
 130                                              'blog_pagecaches_enabled' => new xmlrpcval( $system_stats['blog_pagecaches_enabled'], 'int' ),
 131                                              'db_version' => new xmlrpcval( $system_stats['db_version'], 'string'),    // If a version >95% we make it the new default.
 132                                              'db_utf8' => new xmlrpcval( $system_stats['db_utf8'] ? 1 : 0, 'int' ),    // if support >95%, we'll make it the default
 133                                              // How many "low security" hosts still active?; we'd like to standardize security best practices... on suphp?
 134                                              'php_uid' => new xmlrpcval( $system_stats['php_uid'], 'int' ),
 135                                              'php_uname' => new xmlrpcval( $system_stats['php_uname'], 'string' ),    // Potential unsecure hosts will use names like 'nobody', 'www-data'
 136                                              'php_gid' => new xmlrpcval( $system_stats['php_gid'], 'int' ),
 137                                              'php_gname' => new xmlrpcval( $system_stats['php_gname'], 'string' ),    // Potential unsecure hosts will use names like 'nobody', 'www-data'
 138                                              'php_version' => new xmlrpcval( $system_stats['php_version'], 'string' ),            // Target minimum version: PHP 5.2
 139                                              'php_reg_globals' => new xmlrpcval( $system_stats['php_reg_globals'] ? 1 : 0, 'int' ), // if <5% we may actually refuse to run future version on this
 140                                              'php_allow_url_include' => new xmlrpcval( $system_stats['php_allow_url_include'] ? 1 : 0, 'int' ),
 141                                              'php_allow_url_fopen' => new xmlrpcval( $system_stats['php_allow_url_fopen'] ? 1 : 0, 'int' ),
 142                                              // TODO php_magic quotes
 143                                              'php_upload_max' => new xmlrpcval( $system_stats['php_upload_max'], 'int' ),
 144                                              'php_post_max' => new xmlrpcval( $system_stats['php_post_max'], 'int' ),
 145                                              'php_memory' => new xmlrpcval( $system_stats['php_memory'], 'int'), // how much room does b2evo have to move on a typical server?
 146                                              'php_mbstring' => new xmlrpcval( $system_stats['php_mbstring'] ? 1 : 0, 'int' ),
 147                                              'php_xml' => new xmlrpcval( $system_stats['php_xml'] ? 1 : 0, 'int' ),
 148                                              'php_imap' => new xmlrpcval( $system_stats['php_imap'] ? 1 : 0, 'int' ),    // Does it make sense to rely on IMAP to handle undelivered emails (for user registrations/antispam)
 149                                              'php_opcode_cache' => new xmlrpcval( $system_stats['php_opcode_cache'], 'string' ), // How many use one? Which is the most popular?
 150                                              'gd_version' => new xmlrpcval( $system_stats['gd_version'], 'string' ),
 151                                              // TODO: add missing system stats
 152                                          ), 'struct' ),
 153                                  )
 154                              );
 155  
 156      $result = $client->send($message);
 157  
 158      if( $ret = xmlrpc_logresult( $result, $Messages, false ) )
 159      { // Response is not an error, let's process it:
 160          $response = $result->value();
 161          if( $response->kindOf() == 'struct' )
 162          { // Decode struct:
 163              $response = xmlrpc_decode_recurse($response);
 164  
 165              /**
 166               * @var AbstractSettings
 167               */
 168              global $global_Cache;
 169  
 170              foreach( $response as $key=>$data )
 171              {
 172                  $global_Cache->set( $key, serialize($data) );
 173              }
 174  
 175              $global_Cache->delete( 'evonet_updates' );    // Cleanup
 176  
 177              $global_Cache->dbupdate();
 178  
 179              $Settings->set( 'evonet_last_update', $servertimenow );
 180              $Settings->set( 'evonet_last_version_checked', $version_id );
 181              $Settings->dbupdate();
 182  
 183              $Debuglog->add( 'Updates saved', 'evonet' );
 184  
 185              $Timer->pause('evonet: check for updates');
 186              return true;
 187          }
 188          else
 189          {
 190              $Debuglog->add( 'Invalid updates received', 'evonet' );
 191              $Messages->add( T_('Invalid updates received'), 'error' );
 192          }
 193      }
 194  
 195      $Timer->pause('evonet: check for updates');
 196      return false;
 197  }
 198  
 199  
 200  /**
 201   * Get comments awaiting moderation number
 202   *
 203   * @param integer blog ID
 204   * @return integer
 205   */
 206  function get_comments_awaiting_moderation_number( $blog_ID )
 207  {
 208      global $DB;
 209  
 210      $BlogCache = & get_BlogCache();
 211      $Blog = & $BlogCache->get_by_ID( $blog_ID, false, false );
 212      $moderation_statuses = $Blog->get_setting( 'moderation_statuses' );
 213      $moderation_statuses_condition = '\''.str_replace( ',', '\',\'', $moderation_statuses ).'\'';
 214  
 215      $sql = 'SELECT COUNT(DISTINCT(comment_ID))
 216                  FROM T_comments
 217                      INNER JOIN T_items__item ON comment_post_ID = post_ID ';
 218  
 219      $sql .= 'INNER JOIN T_postcats ON post_ID = postcat_post_ID
 220                  INNER JOIN T_categories othercats ON postcat_cat_ID = othercats.cat_ID ';
 221  
 222      $sql .= 'WHERE '.$Blog->get_sql_where_aggregate_coll_IDs('othercats.cat_blog_ID');
 223      $sql .= ' AND comment_type IN (\'comment\',\'trackback\',\'pingback\') ';
 224      $sql .= ' AND comment_status IN ( '.$moderation_statuses_condition.' )';
 225      $sql .= ' AND '.statuses_where_clause();
 226  
 227      return $DB->get_var( $sql );
 228  }
 229  
 230  
 231  /**
 232   * Show comments awaiting moderation
 233   *
 234   * @todo fp> move this to a more appropriate place
 235   *
 236   * @param integer blog ID
 237   * @param object CommentList
 238   * @param integer limit
 239   * @param array comment IDs to exclude
 240   * @param boolean TRUE - for script
 241   */
 242  function show_comments_awaiting_moderation( $blog_ID, $CommentList = NULL, $limit = 5, $comment_IDs = array(), $script = true )
 243  {
 244      global $current_User, $dispatcher;
 245  
 246      if( is_null( $CommentList ) )
 247      { // Inititalize CommentList
 248          $BlogCache = & get_BlogCache();
 249          $Blog = & $BlogCache->get_by_ID( $blog_ID, false, false );
 250  
 251          $CommentList = new CommentList2( $Blog, NULL, 'CommentCache', 'cmnt_fullview_', 'fullview' );
 252          $exlude_ID_list = NULL;
 253          if( !empty($comment_IDs) )
 254          {
 255              $exlude_ID_list = '-'.implode( ",", $comment_IDs );
 256          }
 257  
 258          $moderation_statuses = explode( ',', $Blog->get_setting( 'moderation_statuses' ) );
 259  
 260          // Filter list:
 261          $CommentList->set_filters( array(
 262                  'types' => array( 'comment', 'trackback', 'pingback' ),
 263                  'statuses' => $moderation_statuses,
 264                  'comment_ID_list' => $exlude_ID_list,
 265                  'post_statuses' => array( 'published', 'community', 'protected' ),
 266                  'order' => 'DESC',
 267                  'comments' => $limit,
 268              ) );
 269  
 270          // Get ready for display (runs the query):
 271          $CommentList->display_init();
 272      }
 273  
 274      $new_comment_IDs = array();
 275      while( $Comment = & $CommentList->get_next() )
 276      { // Loop through comments:
 277          $new_comment_IDs[] = $Comment->ID;
 278  
 279          echo '<div id="comment_'.$Comment->ID.'" class="dashboard_post dashboard_post_'.($CommentList->current_idx % 2 ? 'even' : 'odd' ).'">';
 280          echo '<div class="floatright"><span class="note status_'.$Comment->status.'"><span>';
 281          $Comment->status();
 282          echo '</span></span></div>';
 283  
 284          if( ( $Comment->status !== 'draft' ) || ( $Comment->author_user_ID == $current_User->ID ) )
 285          {// Display Comment permalink icon
 286              echo '<span style="float: left; padding-right: 5px; margin-top: 4px">'.$Comment->get_permanent_link( '#icon#' ).'</span>';
 287          }
 288          echo '<h3 class="dashboard_post_title">';
 289          echo $Comment->get_title( array(
 290                  'author_format' => '<strong>%s</strong>',
 291                  'link_text'     => 'avatar',
 292                  'thumb_size'    => 'crop-top-15x15',
 293              ) );
 294          $comment_Item = & $Comment->get_Item();
 295          echo ' '.T_('in response to')
 296                  .' <a href="?ctrl=items&amp;blog='.$comment_Item->get_blog_ID().'&amp;p='.$comment_Item->ID.'"><strong>'.$comment_Item->dget('title').'</strong></a>';
 297  
 298          echo '</h3>';
 299  
 300          echo '<div class="notes">';
 301          $Comment->rating( array(
 302                  'before'      => '<div class="dashboard_rating">',
 303                  'after'       => '</div> &bull; ',
 304              ) );
 305          $Comment->date();
 306          $Comment->author_url_with_actions( '', true );
 307          $Comment->author_email( '', ' &bull; Email: <span class="bEmail">', '</span> &bull; ' );
 308          $Comment->author_ip( 'IP: <span class="bIP">', '</span> ', true );
 309          $Comment->ip_country();
 310          $Comment->spam_karma( ' &bull; '.T_('Spam Karma').': %s%', ' &bull; '.T_('No Spam Karma') );
 311          echo '</div>';
 312  
 313          echo '<div class="small">';
 314          $Comment->content( 'htmlbody', true );
 315          echo '</div>';
 316  
 317          echo '<div class="dashboard_action_area">';
 318          // Display edit button if current user has the rights:
 319          $redirect_to = NULL;
 320          if( ! $script )
 321          { // Set page, where to redirect, because the function is called from async.php (regenerate_url gives => async.php)
 322              global $admin_url;
 323              $redirect_to = $admin_url.'?ctrl=dashboard&blog='.$blog_ID;
 324          }
 325  
 326          echo '<div class="floatleft">';
 327  
 328          $Comment->edit_link( ' ', ' ', get_icon( 'edit' ), '#', 'roundbutton', '&amp;', true, $redirect_to );
 329  
 330          echo '<span class="roundbutton_group">';
 331          // Display publish NOW button if current user has the rights:
 332          $Comment->publish_link( '', '', '#', '#', 'roundbutton_text', '&amp;', true, true );
 333  
 334          // Display deprecate button if current user has the rights:
 335          $Comment->deprecate_link( '', '', '#', '#', 'roundbutton_text', '&amp;', true, true );
 336  
 337          // Display delete button if current user has the rights:
 338          $Comment->delete_link( '', '', '#', '#', 'roundbutton_text', false, '&amp;', true, true );
 339          echo '</span>';
 340  
 341          echo '</div>';
 342  
 343          // Display Spam Voting system
 344          $vote_spam_params = array();
 345          if( ! $script )
 346          { // This is an async request, so javascript is enabled for sure and we may display voting
 347              $vote_spam_params['display'] = true;
 348          }
 349          $Comment->vote_spam( '', '', '&amp;', true, true, $vote_spam_params );
 350  
 351          echo '<div class="clear"></div>';
 352          echo '</div>';
 353          echo '</div>';
 354      }
 355  
 356      if( !$script )
 357      {
 358          echo '<input type="hidden" id="new_badge" value="'.$CommentList->total_rows.'"/>';
 359      }
 360  }
 361  
 362  
 363  /**
 364   * Get a count of the records in the DB table
 365   *
 366   * @param string Table name
 367   * @return integer A count of the records
 368   */
 369  function get_table_count( $table_name )
 370  {
 371      global $DB;
 372  
 373      $SQL = new SQL();
 374      $SQL->SELECT( 'COUNT( * )' );
 375      $SQL->FROM( $table_name );
 376  
 377      return $DB->get_var( $SQL->get() );
 378  }
 379  
 380  
 381  /**
 382   * Dispaly posts awaiting moderation with the given status
 383   *
 384   * @param string visibility status
 385   * @param object block_item_Widget
 386   * @return boolean true if items were displayed, false otherwise
 387   */
 388  function display_posts_awaiting_moderation( $status, & $block_item_Widget )
 389  {
 390      global $Blog, $current_User;
 391  
 392      // Create empty List:
 393      $ItemList = new ItemList2( $Blog, NULL, NULL );
 394  
 395      // Filter list:
 396      $ItemList->set_filters( array(
 397              'visibility_array' => array( $status ),
 398              'orderby' => 'datemodified',
 399              'order' => 'DESC',
 400              'posts' => 5,
 401          ) );
 402  
 403      // Get ready for display (runs the query):
 404      $ItemList->display_init();
 405  
 406      if( !$ItemList->result_num_rows )
 407      { // We don't have posts awaiting moderation with the given status
 408          return false;
 409      }
 410  
 411      switch( $status )
 412      {
 413          case 'draft':
 414              $block_title = T_('Recent drafts');
 415              break;
 416  
 417          case 'review':
 418              $block_title = T_('Recent posts to review');
 419              break;
 420  
 421          case 'protected':
 422              $block_title = T_('Recent member posts awaiting moderation');
 423              break;
 424  
 425          case 'community':
 426              $block_title = T_('Recent community posts awaiting moderation');
 427              break;
 428  
 429          default:
 430              $block_title = T_('Recent posts awaiting moderation');
 431              break;
 432      }
 433      $block_item_Widget->title = $block_title;
 434      $block_item_Widget->disp_template_replaced( 'block_start' );
 435  
 436      while( $Item = & $ItemList->get_item() )
 437      {
 438          echo '<div class="dashboard_post dashboard_post_'.($ItemList->current_idx % 2 ? 'even' : 'odd' ).'" lang="'.$Item->get('locale').'">';
 439          // We don't switch locales in the backoffice, since we use the user pref anyway
 440          // Load item's creator user:
 441          $Item->get_creator_User();
 442  
 443          $Item->status( array(
 444                  'before' => '<div class="floatright"><span class="note status_'.$Item->status.'"><span>',
 445                  'after'  => '</span></span></div>',
 446              ) );
 447  
 448          echo '<div class="dashboard_float_actions">';
 449          $Item->edit_link( array( // Link to backoffice for editing
 450                  'before'    => ' ',
 451                  'after'     => ' ',
 452                  'class'     => 'ActionButton btn'
 453              ) );
 454          $Item->publish_link( '', '', '#', '#', 'PublishButton' );
 455          echo get_icon( 'pixel' );
 456          echo '</div>';
 457  
 458          if( ( $Item->status !== 'draft' ) || ( $Item->creator_user_ID == $current_User->ID ) )
 459          { // Display Item permalink icon
 460              echo '<span style="float: left; padding-right: 5px; margin-top: 4px">'.$Item->get_permanent_link( '#icon#' ).'</span>';
 461          }
 462          echo '<h3 class="dashboard_post_title">';
 463          $item_title = $Item->dget('title');
 464          if( ! strlen($item_title) )
 465          {
 466              $item_title = '['.format_to_output(T_('No title')).']';
 467          }
 468          echo '<a href="?ctrl=items&amp;blog='.$Blog->ID.'&amp;p='.$Item->ID.'">'.$item_title.'</a>';
 469          echo ' <span class="dashboard_post_details">';
 470          echo '</span>';
 471          echo '</h3>';
 472  
 473          echo '</div>';
 474      }
 475  
 476      $block_item_Widget->disp_template_raw( 'block_end' );
 477  
 478      return true;
 479  }
 480  
 481  ?>

title

Description

title

Description

title

Description

title

title

Body