ref = (string) $ref; } /** * The file-type slug, e.g. `'post'`, `'user'`, `'folder'`. * * @return string */ abstract public static function type(): string; /** * Human-readable title displayed under the tile. * * @return string */ abstract public function title(): string; /** * Reference accessor — read-only on purpose. * * @return string */ public function ref(): string { return $this->ref; } /** * Dashicon class (or `data:` URI) rendered on the tile. Default * is the generic media glyph; subclasses should override. * * @return string */ public function icon(): string { return 'dashicons-media-default'; } /** * Optional preview-image URL (e.g. featured image, avatar, * attachment thumbnail). Empty string when the tile should * render the icon instead. * * @return string */ public function preview_url(): string { return ''; } /** * Whether `$user_id` can see / open this file. Defaults to * `true`; subclasses tighten the gate. For shared folders this * is consulted PER PLACEMENT at snapshot time so a folder * shared with role `editor` cannot expose individual files the * viewer lacks the cap to read. * * @param int $user_id Viewer. * @return bool */ public function can_read( int $user_id ): bool { return true; } /** * Whether the underlying entity still exists. The renderer uses * this to flag dead references with a placeholder tile rather * than rendering nothing (so the user can right-click → remove). * * @return bool */ public function exists(): bool { return '' !== $this->ref; } /** * Shape sent to JS. Subclasses extend by overriding and * `array_merge`'ing on top of `parent::serialize()`. * * @return array */ public function serialize(): array { $shape = array( 'type' => static::type(), 'ref' => $this->ref, 'title' => openstation_plain_text_title( $this->title() ), 'icon' => $this->icon(), 'previewUrl' => $this->preview_url(), 'exists' => $this->exists(), ); /** * Filters the serialized shape of a desktop file before it * crosses the wire. Last-mile mutation point — plugins use * this to attach badges, override labels, or splice in * custom render hints without subclassing. * * @param array $shape The serialized file shape. * @param OpenStation_File $file The file being serialized. */ return apply_filters( 'openstation_file_serialize', $shape, $this ); } }