Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 401 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  declare(strict_types=1);
  18  
  19  namespace core_blog\reportbuilder\local\entities;
  20  
  21  use blog_entry_attachment;
  22  use context_system;
  23  use lang_string;
  24  use stdClass;
  25  use core_reportbuilder\local\entities\base;
  26  use core_reportbuilder\local\filters\{boolean_select, date, select, text};
  27  use core_reportbuilder\local\helpers\format;
  28  use core_reportbuilder\local\report\{column, filter};
  29  
  30  /**
  31   * Blog entity
  32   *
  33   * @package     core_blog
  34   * @copyright   2022 Paul Holden <paulh@moodle.com>
  35   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class blog extends base {
  38  
  39      /**
  40       * Database tables that this entity uses and their default aliases
  41       *
  42       * @return array
  43       */
  44      protected function get_default_table_aliases(): array {
  45          return [
  46              'post' => 'bp',
  47              'tag_instance' => 'bti',
  48              'tag' => 'bt',
  49          ];
  50      }
  51  
  52      /**
  53       * The default title for this entity
  54       *
  55       * @return lang_string
  56       */
  57      protected function get_default_entity_title(): lang_string {
  58          return new lang_string('blog', 'core_blog');
  59      }
  60  
  61      /**
  62       * Initialise the entity
  63       *
  64       * @return base
  65       */
  66      public function initialise(): base {
  67          $columns = $this->get_all_columns();
  68          foreach ($columns as $column) {
  69              $this->add_column($column);
  70          }
  71  
  72          // All the filters defined by the entity can also be used as conditions.
  73          $filters = $this->get_all_filters();
  74          foreach ($filters as $filter) {
  75              $this
  76                  ->add_filter($filter)
  77                  ->add_condition($filter);
  78          }
  79  
  80          return $this;
  81      }
  82  
  83      /**
  84       * Returns list of all available columns
  85       *
  86       * @return column[]
  87       */
  88      protected function get_all_columns(): array {
  89          global $DB;
  90  
  91          $postalias = $this->get_table_alias('post');
  92  
  93          // Title.
  94          $columns[] = (new column(
  95              'title',
  96              new lang_string('entrytitle', 'core_blog'),
  97              $this->get_entity_name()
  98          ))
  99              ->add_joins($this->get_joins())
 100              ->set_type(column::TYPE_TEXT)
 101              ->add_fields("{$postalias}.subject")
 102              ->set_is_sortable(true);
 103  
 104          // Body.
 105          $summaryfieldsql = "{$postalias}.summary";
 106          if ($DB->get_dbfamily() === 'oracle') {
 107              $summaryfieldsql = $DB->sql_order_by_text($summaryfieldsql, 1024);
 108          }
 109  
 110          $columns[] = (new column(
 111              'body',
 112              new lang_string('entrybody', 'core_blog'),
 113              $this->get_entity_name()
 114          ))
 115              ->add_joins($this->get_joins())
 116              ->set_type(column::TYPE_LONGTEXT)
 117              ->add_field($summaryfieldsql, 'summary')
 118              ->add_fields("{$postalias}.summaryformat, {$postalias}.id")
 119              ->add_callback(static function(?string $summary, stdClass $blog): string {
 120                  global $CFG;
 121                  require_once("{$CFG->libdir}/filelib.php");
 122  
 123                  if ($summary === null) {
 124                      return '';
 125                  }
 126  
 127                  // All blog files are stored in system context.
 128                  $context = context_system::instance();
 129                  $summary = file_rewrite_pluginfile_urls($summary, 'pluginfile.php', $context->id, 'blog', 'post', $blog->id);
 130  
 131                  return format_text($summary, $blog->summaryformat, ['context' => $context->id]);
 132              });
 133  
 134          // Attachment.
 135          $columns[] = (new column(
 136              'attachment',
 137              new lang_string('attachment', 'core_repository'),
 138              $this->get_entity_name()
 139          ))
 140              ->add_joins($this->get_joins())
 141              ->set_type(column::TYPE_BOOLEAN)
 142              ->add_fields("{$postalias}.attachment, {$postalias}.id")
 143              ->add_callback(static function(?bool $attachment, stdClass $post): string {
 144                  global $CFG, $PAGE;
 145                  require_once("{$CFG->dirroot}/blog/locallib.php");
 146  
 147                  if (!$attachment) {
 148                      return '';
 149                  }
 150  
 151                  $renderer = $PAGE->get_renderer('core_blog');
 152                  $attachments = '';
 153  
 154                  // Loop over attached files, use blog renderer to generate appropriate content.
 155                  $files = get_file_storage()->get_area_files(context_system::instance()->id, 'blog', 'attachment', $post->id,
 156                      'filename', false);
 157                  foreach ($files as $file) {
 158                      $attachments .= $renderer->render(new blog_entry_attachment($file, $post->id));
 159                  }
 160  
 161                  return $attachments;
 162              })
 163              ->set_disabled_aggregation_all();
 164  
 165          // Publish state.
 166          $columns[] = (new column(
 167              'publishstate',
 168              new lang_string('publishto', 'core_blog'),
 169              $this->get_entity_name()
 170          ))
 171              ->add_joins($this->get_joins())
 172              ->set_type(column::TYPE_TEXT)
 173              ->add_fields("{$postalias}.publishstate")
 174              ->set_is_sortable(true)
 175              ->add_callback(static function(?string $publishstate): string {
 176                  $states = [
 177                      'draft' => new lang_string('publishtonoone', 'core_blog'),
 178                      'site' => new lang_string('publishtosite', 'core_blog'),
 179                      'public' => new lang_string('publishtoworld', 'core_blog'),
 180                  ];
 181  
 182                  return (string) ($states[$publishstate] ?? $publishstate ?? '');
 183              });
 184  
 185          // Time created.
 186          $columns[] = (new column(
 187              'timecreated',
 188              new lang_string('timecreated', 'core_reportbuilder'),
 189              $this->get_entity_name()
 190          ))
 191              ->add_joins($this->get_joins())
 192              ->set_type(column::TYPE_TIMESTAMP)
 193              ->add_fields("{$postalias}.created")
 194              ->set_is_sortable(true)
 195              ->add_callback([format::class, 'userdate']);
 196  
 197          // Time modified.
 198          $columns[] = (new column(
 199              'timemodified',
 200              new lang_string('timemodified', 'core_reportbuilder'),
 201              $this->get_entity_name()
 202          ))
 203              ->add_joins($this->get_joins())
 204              ->set_type(column::TYPE_TIMESTAMP)
 205              ->add_fields("{$postalias}.lastmodified")
 206              ->set_is_sortable(true)
 207              ->add_callback([format::class, 'userdate']);
 208  
 209          return $columns;
 210      }
 211  
 212      /**
 213       * Return list of all available filters
 214       *
 215       * @return filter[]
 216       */
 217      protected function get_all_filters(): array {
 218          global $DB;
 219  
 220          $postalias = $this->get_table_alias('post');
 221  
 222          // Title.
 223          $filters[] = (new filter(
 224              text::class,
 225              'title',
 226              new lang_string('entrytitle', 'core_blog'),
 227              $this->get_entity_name(),
 228              "{$postalias}.subject"
 229          ))
 230              ->add_joins($this->get_joins());
 231  
 232          // Body.
 233          $filters[] = (new filter(
 234              text::class,
 235              'body',
 236              new lang_string('entrybody', 'core_blog'),
 237              $this->get_entity_name(),
 238              $DB->sql_cast_to_char("{$postalias}.summary")
 239          ))
 240              ->add_joins($this->get_joins());
 241  
 242          // Attachment.
 243          $filters[] = (new filter(
 244              boolean_select::class,
 245              'attachment',
 246              new lang_string('attachment', 'core_repository'),
 247              $this->get_entity_name(),
 248              $DB->sql_cast_char2int("{$postalias}.attachment")
 249          ))
 250              ->add_joins($this->get_joins());
 251  
 252          // Publish state.
 253          $filters[] = (new filter(
 254              select::class,
 255              'publishstate',
 256              new lang_string('publishto', 'core_blog'),
 257              $this->get_entity_name(),
 258              "{$postalias}.publishstate"
 259          ))
 260              ->add_joins($this->get_joins())
 261              ->set_options([
 262                  'draft' => new lang_string('publishtonoone', 'core_blog'),
 263                  'site' => new lang_string('publishtosite', 'core_blog'),
 264                  'public' => new lang_string('publishtoworld', 'core_blog'),
 265              ]);
 266  
 267          // Time created.
 268          $filters[] = (new filter(
 269              date::class,
 270              'timecreated',
 271              new lang_string('timecreated', 'core_reportbuilder'),
 272              $this->get_entity_name(),
 273              "{$postalias}.created"
 274          ))
 275              ->add_joins($this->get_joins())
 276              ->set_limited_operators([
 277                  date::DATE_ANY,
 278                  date::DATE_CURRENT,
 279                  date::DATE_LAST,
 280                  date::DATE_RANGE,
 281              ]);
 282  
 283          // Time modified.
 284          $filters[] = (new filter(
 285              date::class,
 286              'timemodified',
 287              new lang_string('timemodified', 'core_reportbuilder'),
 288              $this->get_entity_name(),
 289              "{$postalias}.lastmodified"
 290          ))
 291              ->add_joins($this->get_joins())
 292              ->set_limited_operators([
 293                  date::DATE_ANY,
 294                  date::DATE_CURRENT,
 295                  date::DATE_LAST,
 296                  date::DATE_RANGE,
 297              ]);
 298  
 299          return $filters;
 300      }
 301  
 302      /**
 303       * Return joins necessary for retrieving tags
 304       *
 305       * @return string[]
 306       */
 307      public function get_tag_joins(): array {
 308          $postalias = $this->get_table_alias('post');
 309          $taginstancealias = $this->get_table_alias('tag_instance');
 310          $tagalias = $this->get_table_alias('tag');
 311  
 312          return [
 313              "LEFT JOIN {tag_instance} {$taginstancealias}
 314                      ON {$taginstancealias}.component = 'core'
 315                     AND {$taginstancealias}.itemtype = 'post'
 316                     AND {$taginstancealias}.itemid = {$postalias}.id",
 317              "LEFT JOIN {tag} {$tagalias}
 318                      ON {$tagalias}.id = {$taginstancealias}.tagid",
 319          ];
 320      }
 321  }