Merge branch 'MDL-53515-master' of git://github.com/merrill-oakland/moodle
[moodle.git] / search / classes / document.php
index 89f0d83..c030fef 100644 (file)
@@ -68,6 +68,16 @@ class document implements \renderable, \templatable {
      */
     protected $contentitemid = null;
 
+    /**
+     * @var bool Should be set to true if document hasn't been indexed before. False if unknown.
+     */
+    protected $isnew = false;
+
+    /**
+     * @var \stored_file[] An array of stored files to attach to the document.
+     */
+    protected $files = array();
+
     /**
      * All required fields any doc should contain.
      *
@@ -156,9 +166,21 @@ class document implements \renderable, \templatable {
             'type' => 'text',
             'stored' => true,
             'indexed' => true
-        ),
+        )
     );
 
+    /**
+     * Any fields that are engine specifc. These are fields that are solely used by a search engine plugin
+     * for internal purposes.
+     *
+     * Field names should be prefixed with engine name to avoid potential conflict with core fields.
+     *
+     * Uses same format as fields above.
+     *
+     * @var array
+     */
+    protected static $enginefields = array();
+
     /**
      * We ensure that the document has a unique id across search areas.
      *
@@ -178,6 +200,40 @@ class document implements \renderable, \templatable {
         $this->data['itemid'] = intval($itemid);
     }
 
+    /**
+     * Add a stored file to the document.
+     *
+     * @param \stored_file|int $file The file to add, or file id.
+     * @return void
+     */
+    public function add_stored_file($file) {
+        if (is_numeric($file)) {
+            $this->files[$file] = $file;
+        } else {
+            $this->files[$file->get_id()] = $file;
+        }
+    }
+
+    /**
+     * Returns the array of attached files.
+     *
+     * @return \stored_file[]
+     */
+    public function get_files() {
+        // The files array can contain stored file ids, so we need to get instances if asked.
+        foreach ($this->files as $id => $listfile) {
+            if (is_numeric($listfile)) {
+                $fs = get_file_storage();
+
+                if ($file = $fs->get_file_by_id($id)) {
+                    $this->files[$id] = $file;
+                }
+            }
+        }
+
+        return $this->files;
+    }
+
     /**
      * Setter.
      *
@@ -197,6 +253,8 @@ class document implements \renderable, \templatable {
             $fielddata = static::$requiredfields[$fieldname];
         } else if (!empty(static::$optionalfields[$fieldname])) {
             $fielddata = static::$optionalfields[$fieldname];
+        } else if (!empty(static::$enginefields[$fieldname])) {
+            $fielddata = static::$enginefields[$fieldname];
         }
 
         if (empty($fielddata)) {
@@ -268,13 +326,31 @@ class document implements \renderable, \templatable {
         return (isset($this->data[$field]) || isset($this->extradata[$field]));
     }
 
+    /**
+     * Set if this is a new document. False if unknown.
+     *
+     * @param bool $new
+     */
+    public function set_is_new($new) {
+       $this->isnew = (bool)$new;
+    }
+
+    /**
+     * Returns if the document is new. False if unknown.
+     *
+     * @return bool
+     */
+    public function get_is_new() {
+       return $this->isnew;
+    }
+
     /**
      * Returns all default fields definitions.
      *
      * @return array
      */
     public static function get_default_fields_definition() {
-        return static::$requiredfields + static::$optionalfields;
+        return static::$requiredfields + static::$optionalfields + static::$enginefields;
     }
 
     /**
@@ -350,7 +426,7 @@ class document implements \renderable, \templatable {
      * @return void
      */
     public function set_data_from_engine($docdata) {
-        $fields = static::$requiredfields + static::$optionalfields;
+        $fields = static::$requiredfields + static::$optionalfields + static::$enginefields;
         foreach ($fields as $fieldname => $field) {
 
             // Optional params might not be there.
@@ -408,6 +484,8 @@ class document implements \renderable, \templatable {
      * @return array
      */
     public function export_for_engine() {
+        // Set any unset defaults.
+        $this->apply_defaults();
 
         // We don't want to affect the document instance.
         $data = $this->data;
@@ -433,7 +511,8 @@ class document implements \renderable, \templatable {
 
         }
 
-        foreach (static::$optionalfields as $fieldname => $field) {
+        $fields = static::$optionalfields + static::$enginefields;
+        foreach ($fields as $fieldname => $field) {
             if (!isset($data[$fieldname])) {
                 continue;
             }
@@ -452,6 +531,18 @@ class document implements \renderable, \templatable {
         return $data;
     }
 
+    /**
+     * Apply any defaults to unset fields before export. Called after document building, but before export.
+     *
+     * Sub-classes of this should make sure to call parent::apply_defaults().
+     */
+    protected function apply_defaults() {
+        // Set the default type, TYPE_TEXT.
+        if (!isset($this->data['type'])) {
+            $this->data['type'] = manager::TYPE_TEXT;
+        }
+    }
+
     /**
      * Export the document data to be used as a template context.
      *
@@ -479,6 +570,22 @@ class document implements \renderable, \templatable {
             'description2' => $this->is_set('description2') ? $this->format_text($this->get('description2')) : null,
         ];
 
+        // Now take any attached any files.
+        $files = $this->get_files();
+        if (!empty($files)) {
+            if (count($files) > 1) {
+                $filenames = array();
+                foreach ($files as $file) {
+                    $filenames[] = $file->get_filename();
+                }
+                $data['multiplefiles'] = true;
+                $data['filenames'] = $filenames;
+            } else {
+                $file = reset($files);
+                $data['filename'] = $file->get_filename();
+            }
+        }
+
         if ($this->is_set('userid')) {
             $data['userurl'] = new \moodle_url('/user/view.php', array('id' => $this->get('userid'), 'course' => $this->get('courseid')));
             $data['userfullname'] = format_string($this->get('userfullname'), true, array('context' => $this->get('contextid')));