<?php

/**
 * SPIP, Système de publication pour l'internet
 *
 * Copyright © avec tendresse depuis 2001
 * Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James
 *
 * Ce programme est un logiciel libre distribué sous licence GNU/GPL.
 */

/**
 * Gestion de l'action dissocier_document
 *
 * @package SPIP\Medias\Action
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}

/**
 * Dissocier un document
 *
 * @param string|null $arg
 *     fournit les arguments de la fonction dissocier_document
 *     sous la forme `$id_objet-$objet-$document-suppr-safe`
 *
 *     - 4eme arg : suppr = true, false sinon
 *     - 5eme arg : safe = true, false sinon
 */
function action_dissocier_document_dist($arg = null) {
	if ($arg === null) {
		$securiser_action = charger_fonction('securiser_action', 'inc');
		$arg = $securiser_action();
	}

	// attention au cas ou id_objet est negatif !
	if (strncmp($arg, '-', 1) == 0) {
		$arg = explode('-', substr($arg, 1));
		[$id_objet, $objet, $document] = $arg;
		$id_objet = -$id_objet;
	} else {
		$arg = explode('-', $arg);
		[$id_objet, $objet, $document] = $arg;
	}

	$suppr = $check = false;
	if (count($arg) > 3 and $arg[3] == 'suppr') {
		$suppr = true;
	}
	if (count($arg) > 4 and $arg[4] == 'safe') {
		$check = true;
	}
	if (
		$id_objet = intval($id_objet)
		and (
			($id_objet < 0 and $id_objet == -$GLOBALS['visiteur_session']['id_auteur'])
			or autoriser('dissocierdocuments', $objet, $id_objet)
		)
	) {
		dissocier_document($document, $objet, $id_objet, $suppr, $check);
	} else {
		spip_log("Interdit de modifier $objet $id_objet", 'spip');
	}
}

/**
 * Supprimer un lien entre un document et un objet
 *
 * @param int $id_document
 * @param string $objet
 * @param int $id_objet
 * @param bool $supprime
 *   si true, le document est supprime si plus lie a aucun objet
 * @param bool $check
 *   si true, on verifie les documents references dans le texte de l'objet
 *   et on les associe si pas deja fait
 * @return bool
 */
function supprimer_lien_document($id_document, $objet, $id_objet, $supprime = false, $check = false) {
	if (!$id_document = intval($id_document)) {
		return false;
	}

	// [TODO] le mettre en paramètre de la fonction ?
	$serveur = '';

	// D'abord on ne supprime pas, on dissocie
	include_spip('action/editer_liens');
	objet_dissocier(['document' => $id_document], [$objet => $id_objet], ['role' => '*']);

	// Si c'est une vignette, l'eliminer du document auquel elle appartient
	// cas tordu peu probable
	sql_updateq('spip_documents', ['id_vignette' => 0], 'id_vignette=' . $id_document);

	// verifier son statut apres une suppression de lien
	include_spip('action/editer_document');
	document_instituer($id_document);

	// Invalider les caches
	include_spip('inc/invalideur');
	suivre_invalideur("id='document/$id_document'");

	pipeline(
		'post_edition',
		[
			'args' => [
				'operation' => 'delier_document', // compat v<=2
				'action' => 'delier_document',
				'table' => 'spip_documents',
				'id_objet' => $id_document,
				'objet' => $objet,
				'id' => $id_objet,
			],
			'data' => null,
		]
	);

	if ($check) {
		// si demande, on verifie que ses documents vus sont bien lies !
		$spip_table_objet = table_objet_sql($objet);
		$table_objet = table_objet($objet);
		$id_table_objet = id_table_objet($objet, $serveur);
		$champs = sql_fetsel('*', $spip_table_objet, addslashes($id_table_objet) . '=' . intval($id_objet));

		$marquer_doublons_doc = charger_fonction('marquer_doublons_doc', 'inc');
		$marquer_doublons_doc($champs, $id_objet, $objet, $id_table_objet, $table_objet, $spip_table_objet, '', $serveur);
	}

	// On supprime ensuite s'il est orphelin
	// et si demande
	// ici on ne bloque pas la suppression d'un document rattache a un autre
	if ($supprime and !sql_countsel('spip_documents_liens', "objet!='document' AND id_document=" . $id_document)) {
		$supprimer_document = charger_fonction('supprimer_document', 'action');

		return $supprimer_document($id_document);
	}
}

/**
 * Dissocier un ou des documents
 *
 * @param int|string $document
 *   id_document a dissocier
 *   I/image pour dissocier les images en mode Image
 *   I/document pour dissocier les images en mode document
 *   D/document pour dissocier les documents non image en mode document
 * @param string $objet
 *   objet duquel dissocier
 *   id_objet duquel dissocier
 * @param bool $supprime
 *   supprimer les documents orphelins apres dissociation
 * @param bool $check
 *   verifier le texte des documents et relier les documents references dans l'objet
 */
function dissocier_document($document, $objet, $id_objet, $supprime = false, $check = false) {
	if ($id_document = intval($document)) {
		supprimer_lien_document($id_document, $objet, $id_objet, $supprime, $check);
	} else {
		[$image, $mode] = explode('/', $document);
		$image = ($image == 'I');
		$typdoc = sql_in('docs.extension', ['gif', 'jpg', 'png'], $image ? '' : 'NOT');

		$obj = 'id_objet=' . intval($id_objet) . ' AND objet=' . sql_quote($objet);

		$s = sql_select(
			'docs.id_document',
			'spip_documents AS docs LEFT JOIN spip_documents_liens AS l ON l.id_document=docs.id_document',
			"$obj AND vu='non' AND docs.mode=" . sql_quote($mode) . " AND $typdoc"
		);
		while ($t = sql_fetch($s)) {
			supprimer_lien_document($t['id_document'], $objet, $id_objet, $supprime, $check);
		}
	}

	// pas tres generique ca ...
	if ($objet == 'rubrique') {
		include_spip('inc/rubriques');
		depublier_branche_rubrique_if($id_objet);
	}
}
