/ src / views / MediadetailView.php
<?php
/**
 * SeekQuarry/Yioop --
 * Open Source Pure PHP Search Engine, Crawler, and Indexer
 *
 * Copyright (C) 2009 - 2026  Chris Pollett chris@pollett.org
 *
 * LICENSE:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * END LICENSE
 *
 * @author Chris Pollett chris@pollett.org
 * @license https://www.gnu.org/licenses/ GPL3
 * @link https://www.seekquarry.com/
 * @copyright 2009 - 2026
 * @filesource
 */
namespace seekquarry\yioop\views;

use seekquarry\yioop as B;
use seekquarry\yioop\configs as C;
use seekquarry\yioop\library\CrawlConstants;

/**
 * MediadetailView view used to draw and allow editing of a single media
 * resource when a media resource gallery is draw in detail view.
 * @author Chris Pollett
 */
class MediadetailView extends View implements CrawlConstants
{
    /** This view is drawn on a web layout
     * @var string
     */
    public $layout = "web";
    /**
     * render this method is responsible for drawing both the layout and the
     * view. It should not be modified to change the display of the view (in
     * subclasses). Instead, implement renderView. For MediadetailView, we do
     * override to modify the $data array passed to renderview so as to make
     * sure the background color is set to white
     * @param array $data  an array of values set up by a controller to be used
     *     in rendering the view
     */
    public function render($data)
    {
        $data['BACKGROUND_COLOR'] = 'white';
        $this->layout_object->render($data);
    }
    /**
     * renderView draws details about a particular wiki resource item
     * @param array $data  contains the static page contents the view
     */
    public function renderView($data)
    {
        $read_mode = empty($data['EDIT']);
        $resource = $data['RESOURCE_INFO'];
        $name = $resource['name'];
        $name_parts = pathinfo($name);
        $written_name = $name;
        $use_editable_thumb = false;
        $url_prefix = $data['URL_PREFIX'];
        $folder_prefix = $data['FOLDER_PREFIX'];
        $token_string = (empty($data[C\p('CSRF_TOKEN')])) ? "" :
            C\p('CSRF_TOKEN').'='.$data[C\p('CSRF_TOKEN')];
        $base_url = htmlentities(B\wikiUrl($data['PAGE_NAME'] , true,
            $data['CONTROLLER'], $data['GROUP']['GROUP_ID'])) .
            $token_string;
        if (!empty($data['settings'])) {
            $base_url .= "&settings=" . $data['settings'];
        }
        if (C\REDIRECTS_ON) {
            $original_url_prefix = preg_replace("/\/-\//u", "/$token_string/",
                $data['ORIGINAL_URL_PREFIX']);
            $thumb_prefix =  preg_replace("/\/-\//u", "/$token_string/",
                $data['THUMB_PREFIX']);
            $athumb_prefix =  preg_replace("/\/-\//u", "/$token_string/",
                $data['ATHUMB_PREFIX']);
        } else {
            $original_url_prefix = $data['ORIGINAL_URL_PREFIX'] .
                "&$token_string";
            $thumb_prefix = $data['THUMB_PREFIX'] .
                "&$token_string";
            $athumb_prefix = $data['ATHUMB_PREFIX'] .
                "&$token_string";
        }
        if (!empty($name_parts['extension'])) {
            if (in_array($name_parts['extension'],
                C\EDITABLE_RESOURCE_EXTENSIONS) ||
                in_array(strtolower($name_parts['extension']),
                C\EDITABLE_IMAGE_EXTENSIONS)) {
                $use_editable_thumb = true;
            } elseif (in_array($name_parts['extension'], ['mov',
                'mp4', 'm4v', 'webm', 'mkv', 'm2ts'])) {
                $written_name = $name_parts['filename'] .
                    "[".tl('media_view_video')."]";
            } elseif (in_array($name_parts['extension'], ['wav',
                'mp3','aac', 'aif', 'aiff', 'oga', 'ogg', "m4a"])) {
                $written_name = $name_parts['filename'] .
                    "[".tl('media_view_audio')."]";
            }
        }
        $disabled = " disabled='disabled' ";
        if (!empty($data['CAN_EDIT']) && !empty($resource['is_writable'])) {
            $disabled = "";
        }
        if (!$read_mode) {
            $written_name = $name;
        }
        $thumb_connect = (C\REDIRECTS_ON) ? "/" : "&n=";
        $encode_name = urlencode($name);
        $original_current_url = "$original_url_prefix".
            "$thumb_connect$encode_name";
        $current_url = "$url_prefix&n=$encode_name";
        $clear_url = "$folder_prefix&clear=" .
            $encode_name;
        $current_thumb = "$thumb_prefix$thumb_connect" .
            $encode_name;
        $current_animated_thumb = "$athumb_prefix$thumb_connect" .
            $encode_name;
        if (!empty($data['SUB_PATH'])) {
            if (!str_contains($current_url, "sf=")) {
                $encode_sub_path = urlencode($data['SUB_PATH']);
                $add_sub_path = "&sf=$encode_sub_path";
                $current_url .= $add_sub_path;
                $clear_url .= $add_sub_path;
            }
            if (empty($resource['has_thumb'])) {
                $current_thumb = $data['DEFAULT_THUMB_URL'];
                if (!$read_mode &&!$disabled &&
                    $use_editable_thumb) {
                    $current_thumb = $data['DEFAULT_EDITABLE_THUMB_URL'];
                }
            }
            if (!$read_mode && !$disabled && $use_editable_thumb) {
                $current_url = "$folder_prefix&n=" .
                    "$encode_name&arg=edit";
            }
            if (!empty($resource['is_dir'])) {
                $current_url = $folder_prefix;
                $current_thumb = $data['DEFAULT_FOLDER_THUMB_URL'];
            }
        } else {
            if (empty($resource['has_thumb'])) {
                $current_thumb = $data['DEFAULT_THUMB_URL'];
                if (!$read_mode &&!$disabled &&
                    $use_editable_thumb) {
                    $current_thumb = $data['DEFAULT_EDITABLE_THUMB_URL'];
                }
            }
            if (!$read_mode && !$disabled && $use_editable_thumb) {
                $current_url = "$folder_prefix&n=" .
                    urlencode($name) . "&arg=edit";
            }
            if (!empty($resource['is_dir'])) {
                $current_url = "$folder_prefix&sf=".
                    urlencode($name);
                $current_thumb = $data['DEFAULT_FOLDER_THUMB_URL'];
            }
        }
        $num_files = "";
        if (!empty($resource['is_dir'])) {
            if (isset($resource['num_files'])) {
                $num_files = ". <b>".
                    tl("mediadetail_view_num_files") . "</b>" .
                    $resource['num_files'];
            }
        }
        $img_url = ($read_mode || !empty($resource['is_dir']) || (!$disabled &&
            $use_editable_thumb)) ? $current_url : $original_current_url;
        $animated_thumb_info = "";
        if ($resource['has_animated_thumb']) {
            $animated_thumb_info = "class='animated' " .
                "data-src='$current_animated_thumb' ".
                "onmouseover= 'let src = this.src; ".
                "this.src = this.dataset.src; ".
                "this.dataset.src =src' " .
                "onmouseout= 'let src = this.src; ".
                "this.src = this.dataset.src; ".
                "this.dataset.src =src' ";
        }
        ?>
        <div>
        <div class="media-container center"><?php
        /* The picture and anything drawn over it are kept in one box of
           their own, so that the corner control sits against the
           picture rather than against the whole width of the page. */
        ?><span class="thumb-holder"><a href="<?=$img_url ?>"
            target="_parent" ><img class="photo" id="detail-thumb"
            src="<?= $current_thumb ?>" <?=$animated_thumb_info ?> ><?php
        if (!$read_mode && !empty($data['CAN_EDIT']) &&
            $use_editable_thumb) {
            e("<svg class='resource-edit-pen resource-edit-pen-large' " .
                "viewBox='0 0 16 16' aria-hidden='true'>" .
                "<path d='M11.2,1.6 L14.4,4.8 L6.4,12.8 L2.4,13.6 " .
                "L3.2,9.6 Z' fill='#f5c542' stroke='#7a5c00' " .
                "stroke-width='1' stroke-linejoin='round' />" .
                "<path d='M10,2.8 L13.2,6' fill='none' stroke='#7a5c00' " .
                "stroke-width='1' /></svg>");
        }
        ?></a><?php
        /* Somebody who may edit the page can ask for the small picture
           to be made again, which is what to do when a document was
           saved before this could read its kind, or when the reader
           itself has been improved since. The asking is done on its
           own: the page is not loaded again, and when the answer comes
           back only the picture is fetched afresh. */
        if (!$read_mode && !$disabled && empty($resource['is_dir'])) {
            /* The asking goes to the page the resource lives on, not
               to the resource itself. Built off the resource's own
               address, the ask fetched the document, and a browser that
               cannot show a document downloads it, which is what took
               the reader off the page. */
            $remake_url = $folder_prefix . "&remake_thumb=" .
                $encode_name . "&arg=remake_thumb";
            $thumb_url = $current_thumb;
            ?><a class="remake-thumb" href="javascript:void(0)"
                title="<?= tl('mediadetail_view_remake_thumb') ?>"
                aria-label="<?= tl('mediadetail_view_remake_thumb') ?>"
                onclick='remakeThumb("<?= $remake_url ?>",
                "<?= $thumb_url ?>"); return false;'>&#8635;</a><?php
        }
        ?></span>
        </div>
        <?php
        if ($read_mode) {?>
            <h2 class="center"><?= $written_name ?></h2>
            <?php
        } else {
            e("<h2 class='resource-field center' tabindex='0'>".
                "<input type='text' ".
                "id='resource-media' aria-label='".
                tl('mediadetail_view_name')."' ".
                "value='" . str_replace("'", "&#39;", $name).
                "' $disabled ><br>");
            if (!$disabled) {
                ?><button onclick='parent.renameResource("<?=
                urlencode($name);?>",
                document.getElementById("resource-media"))' ><?=
                tl('mediadetail_view_rename') ?></button><?php
            }
            if (!$disabled && empty($resource['is_dir'])
                && (!isset($data['HEAD']['page_type']) ||
                $data['HEAD']['page_type'] != 'media_list')) { ?>
                <script>
                document.write(
                "<button onclick='parent.addToPage(" + '"<?=
                urlencode($name);
                ?>", "wiki-page"<?= (empty($data['SUB_PATH'])) ?
                "" : ", \"{$data['SUB_PATH']}\""
                ?>)' + "'><?=tl('mediadetail_view_add_to_page')
                ?></button>");
                </script><?php
            }
            $append = "";
            if (isset($data['OTHER_BACK_URL'])) {
                $append .= $data['OTHER_BACK_URL'];
            }
            if (!$disabled && !empty($resource['is_compressed'])) {
                $extract_url = $base_url .
                    "&arg=edit&extract=". urlencode($name) .
                        $append;
                if (!empty($data['SUB_PATH'])) {
                    $extract_url .= "&sf=". urlencode($data['SUB_PATH']);
                }?>
                <a class="media-anchor-button" target="_parent"
                href='<?=$extract_url
                ?>'><?=tl('mediadetail_view_extract');
                ?></a><?php
            }
            $copy_url = $base_url .
                "&arg=edit&clip_copy=". urlencode($name) . $append;
            if (!empty($data['SUB_PATH'])) {
                $copy_url .= "&sf=". urlencode($data['SUB_PATH']);
            }?>
            <a class="media-anchor-button" target="_parent" href='<?=$copy_url
                ?>'><?=tl('mediadetail_view_clip_copy');?></a><?php
            if (!$disabled) {
                $cut_url = $base_url .
                    "&arg=edit&clip_cut=". urlencode($name) . $append;
                if (!empty($data['SUB_PATH'])) {
                    $cut_url .= "&sf=".
                        urlencode($data['SUB_PATH']);
                }?>
                <a class="media-anchor-button" target="_parent"
                href='<?=$cut_url
                ?>'><?=tl('mediadetail_view_clip_cut');?></a><?php
            }
            e("</h2>");
        } ?>
        <div class="gray center">
        <b><?=tl('mediadetail_element_modified') ?></b> <?=date("r",
            $resource['modified']) . $num_files ?>.
        <b><?=tl('mediadetail_element_size')?> </b><?=$resource['size'] ?>.
        </div>
        <div class="media-detail-description" tabindex="0" >
        <h3><?=tl('mediadetail_element_description'); ?></h3><?php
        if ($read_mode) {?>
            <div class='resource-description'><?=
                $data['RESOURCE_DESCRIPTION'];
            ?></div>
            <?php
        } else {
            $arg = ($data['CONTROLLER'] == 'static') ? 'read' :
                ((stristr($data['MODE'],'media-detail') !== false) ? 'edit' :
                $data['MODE']);
            $a = ($data['CONTROLLER'] == 'static') ? 'showPage' : 'wiki';
            $page_name = ($data['CONTROLLER'] == 'static') ? 'p' : 'page_name';
            $child_frame = (!empty($data['TARGET']));
            ?>
            <form <?= $child_frame ? "" : 'target="_parent"' ?>>
            <input type="hidden" name='<?=C\p('CSRF_TOKEN')?>'
                value='<?=$data[C\p('CSRF_TOKEN')]?>' >
            <input type="hidden" name='arg' value='<?=$arg ?>' >
            <input type="hidden" name='a' value='<?=$a ?>' >
            <input type="hidden" name='c' value='<?=$data['CONTROLLER'] ?>' >
            <input type="hidden" name='n' value='<?=$name ?>' ><?=
             ($child_frame) ?
                "<input type='hidden' name='target' value='child' >" : "" ?>
            <input type="hidden" name='<?= $page_name ?>'
                value='<?=$data['PAGE_NAME']?>' >
            <?php
            if (!empty($data['SUB_PATH'])) {
                $sub_path = $data['SUB_PATH'];
                if (!empty($resource['is_dir'])) {
                    $sub_path_parts = explode("/", $data['SUB_PATH']);
                    array_pop($sub_path_parts);
                    $sub_path = implode("/", $sub_path_parts);
                }
                ?>
                <input type="hidden" name='sf'
                    value='<?=$sub_path; ?>' >
                <?php
            }
            ?>
            <textarea name='resource_description'><?=
            $data['RESOURCE_DESCRIPTION'];
            ?></textarea>
            <div>
            <button type="submit"><?=tl('mediadetail_view_save') ?></button>
            </div>
            </form><?php
        } ?>
        </div>
        </div><?php
        if (!$read_mode && !$disabled && empty($resource['is_dir'])) {
            ?><script>
            /* Asks for the picture to be made again and then fetches
               the new one. Nothing else on the page is loaded again,
               and the address the picture is fetched by carries the
               time, so a browser holding the old one shows the new. */
            function remakeThumb(asking, picture)
            {
                let control = document.querySelector(".remake-thumb");
                if (control) {
                    control.classList.add("remake-thumb-working");
                }
                fetch(asking, {credentials: "same-origin",
                    headers: {"X-Requested-With": "XMLHttpRequest"}
                }).then(() => {
                    let shown = document.getElementById("detail-thumb");
                    if (shown) {
                        let joiner = (picture.indexOf("?") < 0) ? "?" : "&";
                        shown.src = picture + joiner + "made=" + Date.now();
                    }
                }).finally(() => {
                    if (control) {
                        control.classList.remove("remake-thumb-working");
                    }
                });
            }
            </script><?php
        }
        ?>
        <?php
    }
}
X