<?php
/**
* This file is part of contao-community-alliance/contao-clipboard-bundle.
*
* (c) 2013 MEN AT WORK.
* (c) 2021 The CCA team.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* This project is provided in good faith and hope to be usable by anyone.
*
* @package Clipboard
* @author Ingolf Steinhardt <info@e-spin.de>
* @copyright 2013 MEN AT WORK.
* @copyright 2021 The CCA team.
* @license https://spdx.org/licenses/LGPL-3.0-or-later.html LGPL-3.0-or-later
* @filesource
*/
namespace ContaoCommunityAlliance\ClipboardBundle\Xml;
use Contao\File;
use Contao\Folder;
/**
* Class ClipboardXml
*/
class Base
{
/**
* @var \Contao\BackendUser|\Contao\User
*/
private $backendUser;
/**
* Contains some helper functions
*
* @var object
*/
protected $helper;
/**
* Contains all function to write xml
*
* @var Writer
*/
protected $xmlWriter;
/**
* Contains all functions to read xml
*
* @var Reader
*/
protected $xmlReader;
/**
* Contains all file operations
*
* @var \Files
*/
protected $files;
/**
* Variables
*/
protected $_arrClipboardElements;
/**
* Base constructor.
*
* @param \ContaoCommunityAlliance\ClipboardBundle\Xml\Reader $xmlReader
*
* @param \ContaoCommunityAlliance\ClipboardBundle\Xml\Writer $xmlWriter
*
* @param \ContaoCommunityAlliance\ClipboardBundle\Helper\Base $clipboardHelper
*
* @param \ContaoCommunityAlliance\ClipboardBundle\Helper\ContaoBridge $contaoBindings
*/
public function __construct($xmlReader, $xmlWriter, $clipboardHelper, $contaoBindings)
{
$this->backendUser = $contaoBindings->getBackendUser();
$this->files = $contaoBindings->getFiles();
$this->xmlReader = $xmlReader;
$this->xmlWriter = $xmlWriter;
$this->helper = $clipboardHelper;
$this->_createClipboardFromFiles();
}
/**
* Set the current favorite to the given position in action with the id
*
* @param string $strPastePos
* @param integer $intId
*/
public function read($strPastePos, $intId)
{
$this->xmlReader->readXml($this->getFavorite(), $strPastePos, $intId);
}
/**
* Unfavor all clipboard elements and write given array to xml file
*
* @param array $arrSet
*/
public function write($arrSet)
{
$objFile = $this->getFavorite();
$this->unFavorAll();
$arrSet['filename'] = $this->_getFileName($arrSet);
$arrSet['path'] = $this->getPath();
if (!$this->xmlWriter->writeXml($arrSet, $this->_arrClipboardElements)) {
$objFile->setFavorite(true);
}
}
/**
* Delete xml file
*
* @param string $strHash
*/
public function deleteFile($strHash)
{
if (is_object($this->_arrClipboardElements[$strHash])) {
$objFile = $this->_arrClipboardElements[$strHash];
if ($this->fileExists($objFile->getFileName())) {
$this->files->delete($this->getPath() . '/' . $objFile->getFileName());
}
}
}
/**
* Edit all given titles
*
* @param array $arrTitles
*/
public function editTitle($arrTitles)
{
foreach ($arrTitles as $hash => $strTitle) {
if (isset($this->_arrClipboardElements[$hash])) {
$this->_arrClipboardElements[$hash]->setTitle($strTitle);
}
}
}
/**
* Check if the given file exists and return boolean
*
* @param string $strFileName
*
* @return boolean
*/
protected function fileExists($strFileName)
{
if (file_exists(TL_ROOT . '/' . $this->getPath() . '/' . $strFileName)) {
return true;
}
return false;
}
/**
* Return if clipboard has elements or not
*
* @return boolean
*/
public function hasElements()
{
return is_array($this->_arrClipboardElements) && count($this->_arrClipboardElements) > 0;
}
/**
* Return if clipboard has favorite elements
*
* return boolean
*/
public function hasFavorite()
{
if (is_object($this->getFavorite())) {
return true;
}
return false;
}
/**
* Get favorite
*
* @return Element
*/
public function getFavorite()
{
$arrFavorits = [];
if ($this->hasElements()) {
foreach ($this->_arrClipboardElements as $objFile) {
if ($objFile->getFavorite()) {
$arrFavorits[] = $objFile;
}
}
if (count($arrFavorits) == 1) {
return $arrFavorits[0];
} else {
$objFileNewest = reset($this->_arrClipboardElements);
foreach ($this->_arrClipboardElements as $objFile) {
if ($objFileNewest->getTimeStemp() < $objFile->getTimeStemp()) {
$objFileNewest = $objFile;
}
}
$this->unFavorAll();
$objFileNewest->setFavorite(true);
return $objFileNewest;
}
}
return false;
}
/**
* Set given file hast to favorite and unfavor all other
*
* @param type $hash
*/
public function setFavor($hash)
{
$this->unFavorAll();
$this->_arrClipboardElements[$hash]->setFavorite(true);
}
/**
* Unfavor all clipboard elements
*/
public function unFavorAll()
{
if ($this->hasElements()) {
foreach ($this->_arrClipboardElements as $objFile) {
$objFile->setFavorite(false);
}
}
}
/**
* Get all clipboard elements
*
* @return array
*/
public function getElements()
{
return $this->_arrClipboardElements;
}
/**
* Fill the clipboard from files
*
* @throws \Exception
*/
protected function _createClipboardFromFiles()
{
$arrFiles = scan(TL_ROOT . '/' . $this->getPath());
if (is_array($arrFiles) && count($arrFiles) > 0) {
foreach ($arrFiles as $strFileName) {
$arrFile = $this->helper->getArrFromFileName($this->getPath() . '/' . $strFileName);
if ($arrFile[0] != $this->helper->getPageType()) {
continue;
}
if ($this->fileExists($strFileName)) {
$objFile = new Element($strFileName, $this->getPath());
$objFile->setHelper($this->helper);
$objFile->setXmlReader($this->xmlReader);
$objFile->setXmlWriter($this->xmlWriter);
$this->_arrClipboardElements[$objFile->getHash()] = $objFile;
}
}
}
}
/**
* Return path to clipboard files for current user
*
* @return string
* @throws \Exception
*/
public function getPath()
{
$objUserFolder = new Folder($GLOBALS['TL_CONFIG']['uploadPath'] . '/clipboard/' . $this->backendUser->username);
$this->_protect($objUserFolder->value);
return $objUserFolder->value;
}
/**
* Protect the folder by adding an .htaccess file
*
* @throws \Exception
*/
protected function _protect($strFolder)
{
if (!file_exists(TL_ROOT . '/' . $strFolder . '/.htaccess')) {
$objFile = new File($strFolder . '/.htaccess');
$objFile->write("order deny,allow\ndeny from all");
$objFile->close();
}
}
/**
* Get new filename
*
* @param array $arrSet
*
* @return string
*/
protected function _getFileName($arrSet)
{
$arrFileName = [
$this->helper->getPageType(),
time(),
'F',
(($arrSet['childs']) ? 'C' : 'NC'),
(($arrSet['grouped']) ? 'G' : 'NG'),
standardize($arrSet['title'])
];
return implode(',', $arrFileName) . '.xml';
}
}