<?php
// +-------------------------------------------------+
// © 2002-2004 PMB Services / www.sigb.net pmb@sigb.net et contributeurs (voir www.sigb.net)
// +-------------------------------------------------+
// $Id: DiffusionPrivateHelper.php,v 1.2.2.2 2026/06/11 13:02:53 jparis Exp $

namespace Pmb\DSI\Helper;

/**
 * Logique propre aux alertes privees (DSI privees) : resolution de l'item
 * editable et extraction de ses donnees de recherche pour le formulaire OPAC.
 */
class DiffusionPrivateHelper
{
    /**
     * Retourne les donnees de recherche d'une alerte privee a editer.
     *
     * Resout dans l'arbre d'items l'item modifie par l'utilisateur (marqueur
     * userModifiedItem) ; a defaut (alertes "legacy" sans marqueur) prend le
     * premier item porteur d'une equation de recherche, puis en extrait les
     * donnees attendues par le formulaire d'edition.
     *
     * @param object $item Item racine de l'alerte privee
     * @return object|null Un objet { serializedSearch, humanQuery, search },
     *                     ou null si aucun item editable n'est trouve
     */
    public static function getSearchData($item)
    {
        $found = self::findUserModifiedItem($item);
        if (null === $found) {
            $found = self::findItemWithSearch($item);
        }
        if (null === $found) {
            return null;
        }
        $data = new \stdClass();
        $data->serializedSearch = $found->itemSource->selector->data->search_serialize;
        $data->humanQuery = $found->getSearchInput();
        $data->search = $found->itemSource->selector->data->search;
        return $data;
    }

    /**
     * Recherche recursivement l'item porteur du marqueur userModifiedItem.
     *
     * Teste l'item courant puis descend dans ses enfants. Retourne le premier
     * item dont settings->userModifiedItem vaut true, ou null si aucun item de
     * l'arbre ne porte ce marqueur.
     *
     * @param object $item Item a parcourir
     * @return object|null L'item modifie par l'utilisateur, ou null
     */
    private static function findUserModifiedItem($item)
    {
        if (is_object($item->settings) && !empty($item->settings->userModifiedItem)) {
            return $item;
        }
        foreach ($item->childs as $child) {
            $found = self::findUserModifiedItem($child);
            if (null !== $found) {
                return $found;
            }
        }
        return null;
    }

    /**
     * Recherche recursivement un item porteur d'une equation de recherche.
     *
     * Repli pour les alertes privees "legacy" qui stockent l'equation
     * directement dans leur item racine, sans marqueur userModifiedItem.
     *
     * @param object $item Item a parcourir
     * @return object|null L'item porteur d'une equation, ou null
     */
    private static function findItemWithSearch($item)
    {
        if (is_object($item->itemSource)
            && isset($item->itemSource->selector)
            && is_object($item->itemSource->selector)
            && isset($item->itemSource->selector->data)
            && is_object($item->itemSource->selector->data)
            && !empty($item->itemSource->selector->data->search_serialize)) {
            return $item;
        }
        foreach ($item->childs as $child) {
            $found = self::findItemWithSearch($child);
            if (null !== $found) {
                return $found;
            }
        }
        return null;
    }
}
