Your IP : 216.73.216.85


Current Path : /home/smartconb/www/armencom33/libraries/sobi/Application/Joomla/
Upload File :
Current File : /home/smartconb/www/armencom33/libraries/sobi/Application/Joomla/FileSystem.php

<?php
/**
 * @package: Sobi Framework
 *
 * @author
 * Name: Sigrid Suski & Radek Suski, Sigsiu.NET GmbH
 * Email: sobi[at]sigsiu.net
 * Url: https://www.Sigsiu.NET
 *
 * @copyright Copyright (C) 2006 - 2023 Sigsiu.NET GmbH (https://www.sigsiu.net). All rights reserved.
 * @license GNU/LGPL Version 3
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 3
 * as published by the Free Software Foundation, and under the additional terms according section 7 of GPL v3.
 * See https://www.gnu.org/licenses/lgpl.html and https://www.sigsiu.net/licenses.
 *
 * 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 Lesser General Public License for more details.
 *
 * @created  Thu, Dec 1, 2016 by Radek Suski
 * @modified 28 February 2023 by Sigrid Suski
 */

//declare( strict_types=1 );

namespace Sobi\Application\Joomla;

defined( 'SOBI' ) || exit( 'Restricted access' );

use DOMDocument;
use Sobi\C;
use Sobi\Error\Exception;
use Sobi\Framework;
use Sobi\Interfaces\Application\FileSystemInterface;
use Sobi\Lib\Instance;
use Joomla\CMS\Filesystem\File as JFile;
use Joomla\CMS\Filesystem\Folder as JFolder;

/**
 * Class FileSystem
 * @package Sobi\FileSystem
 */
class FileSystem implements FileSystemInterface
{
	use Instance;

	/**
	 * @param string $file
	 *
	 * @return bool
	 */
	public function exists( string $file ): bool
	{
		return file_exists( $file );
	}

	/**
	 * @param string $file
	 * @param bool $safe
	 *
	 * @return string
	 */
	public function clean( string $file, bool $safe = false ): string
	{
		$file = str_replace( C::DS, '/', $file );
		$file = preg_replace( '|([^:])(//)+([^/]*)|', '\1/\3', $file );
		$file = str_replace( '__BCKSL__', '\\', preg_replace( '|([^:])(\\\\)+([^\\\])|', "$1__BCKSL__$3", $file ) );
		$file = str_replace( '\\', '/', $file );
		if ( $safe ) {
			$file = Jfile::makeSafe( $file );
		}
		if ( !( strstr( $file, ':' ) ) ) {
			while ( strstr( $file, '//' ) ) {
				$file = str_replace( '//', '/', $file );
			}
		}

		return $file;
	}

	/**
	 * @param string $file
	 *
	 * @return mixed|string
	 */
	public function getExt( string $file ): string
	{
		$ext = explode( ".", $file );
		$ext = $ext[ count( $ext ) - 1 ];

		return $ext == $file ? C::ES : $ext;
	}

	/**
	 * @param string $file
	 *
	 * @return mixed|string
	 */
	public function getFileName( string $file ): string
	{
		$ext = explode( '/', $file );

		return $ext[ count( $ext ) - 1 ];
	}

	/**
	 * @param string $source
	 * @param string $destination
	 *
	 * @return mixed
	 * @throws \Sobi\Error\Exception
	 */
	public function copy( string $source, string $destination )
	{
		$destination = $this->clean( str_replace( '\\', '/', $destination ) );
		$path = explode( '/', str_replace( [ C::ROOT, str_replace( '\\', '/', C::ROOT ) ], C::ES, $destination ) );
		$part = C::ROOT;
		$i = count( $path );
		/** clean the path */
		/** @noinspection PhpExpressionResultUnusedInspection */
		for ( $i; $i != 0; $i-- ) {
			if ( isset( $path[ $i ] ) && !( $path[ $i ] ) ) {
				unset( $path[ $i ] );
			}
		}
		array_pop( $path );
		if ( !( is_string( $path ) ) && count( $path ) ) {
			foreach ( $path as $dir ) {
				$part .= "/$dir";
				if ( $dir && !( file_exists( $part ) ) ) {
					$this->mkdir( $part );
				}
			}
		}
		if ( !( is_dir( $source ) ) ) {
			return Jfile::copy( $this->clean( $source ), $this->clean( $destination ) );
		}
		else {
			return Jfolder::copy( $this->clean( $source ), $this->clean( $destination ) );
		}
	}

	/**
	 * @param string $file
	 *
	 * @return bool|void
	 * @throws \Sobi\Error\Exception
	 */
	public function delete( string $file ): bool
	{
		$file = $this->fixPath( $file );
		if ( is_dir( $file ) ) {
			if ( $file == C::ROOT || dirname( $file ) == C::ROOT ) {
				throw new Exception( Framework::Txt( 'Fatal error. Trying to delete not allowed path "%s"', $file ) );
			}

			return Jfolder::delete( $file );
		}
		else {
			return Jfile::delete( $file );
		}
	}

	/**
	 *     *
	 * @param string $source
	 * @param string $destination
	 *
	 * @return bool
	 */
	public function move( string $source, string $destination ): bool
	{
		return Jfile::move( $source, $destination );
	}

	/**
	 * @param string $file
	 *
	 * @return string
	 */
	public function read( string $file ): string
	{
		return file_get_contents( $file );
	}

	/**
	 * @param string $path
	 *
	 * @return string
	 */
	public function fixPath( string $path ): string
	{
		$sep = explode( '://', $path );
		if ( is_array( $sep ) && isset( $sep[ 1 ] ) ) {
			return $this->fixUrl( $path );
		}

		// remove double and triple slashes
		return str_replace( C::DS . C::DS, C::DS, str_replace( C::DS . C::DS, C::DS, str_replace( '\\', '/', $path ) ) );
	}

	/**
	 * @param string $url
	 *
	 * @return string
	 */
	public function fixUrl( string $url ): string
	{
		$sep = explode( '://', $url );
		if ( is_array( $sep ) && isset( $sep[ 1 ] ) ) {
			return $sep[ 0 ] . '://' . str_replace( C::DS . C::DS, C::DS, str_replace( C::DS . C::DS, C::DS, str_replace( '\\', '/', $sep[ 1 ] ) ) );

		}

		return $this->fixPath( $url );
	}

	/**
	 * @param string $file
	 * @param string $buffer
	 * @param bool $append
	 *
	 * @return bool
	 * @throws \Sobi\Error\Exception
	 */
	public function write( string $file, string $buffer, bool $append = false ): bool
	{
		if ( $append ) {
			$content = $this->read( $file );
			$buffer = $content . $buffer;
		}
		$return = Jfile::write( $file, $buffer );
		if ( $return === false ) {
			throw new Exception( Framework::Error( 'CANNOT_WRITE_TO_FILE_AT', $file ) );
		}
		else {
			return true;
		}
	}

	/**
	 * @param string $name
	 * @param string $destination
	 *
	 * @return bool
	 * @throws \Sobi\Error\Exception
	 */
	public function upload( string $name, string $destination ): bool
	{
		if ( !( file_exists( dirname( $destination ) ) ) ) {
			$this->mkdir( dirname( $destination ) );
		}
		/** Ajax uploader exception
		 * @todo: have to be moved to component
		 */
		if ( strstr( $name, str_replace( '\\', '/', SOBI_PATH ) ) ) {
			return $this->move( $name, $destination );
		}

		return Jfile::upload( $name, $destination, false, true );
	}

	/**
	 * @param string $path
	 * @param string $hex
	 *
	 * @return bool
	 */
	public function chmod( string $path, int $hex ): bool
	{
		return chmod( $path, $hex );
	}

	/**
	 * @param string $path
	 * @param int $mode
	 *
	 * @return bool
	 * @throws \Sobi\Error\Exception
	 */
	public function mkdir( string $path, int $mode = 0755 ): bool
	{
		$path = $this->clean( $path );
		if ( !( JFolder::create( $path, $mode ) ) ) {
			throw new Exception( Framework::Error( 'CANNOT_CREATE_DIR', str_replace( C::ROOT, C::ES, $path ) ) );
		}
		else {
			return true;
		}
	}

	/**
	 * @param string $path
	 *
	 * @return bool
	 */
	public function rmdir( string $path ): bool
	{
		return JFolder::delete( $path );
	}

	/**
	 * @param string $path
	 *
	 * @return bool
	 */
	public function readable( string $path ): bool
	{
		return is_readable( $path );
	}

	/**
	 * @param string $path
	 *
	 * @return bool
	 */
	public function writable( string $path ): bool
	{
		return is_writable( $path );
	}

	/**
	 * @param string $path
	 *
	 * @return int
	 */
	public function owner( string $path ): int
	{
		return fileowner( $path );
	}

	/**
	 * @param string $source
	 * @param string $destination
	 *
	 * @return bool
	 */
	public function rename( string $source, string $destination ): bool
	{
		return $this->move( $source, $destination );
	}

	/**
	 * @param string $file
	 * @param int $options
	 *
	 * @return DOMDocument
	 */
	public function & loadXML( string $file, int $options = 0 ): DOMDocument
	{
		$d = new DOMDocument();
		$d->load( realpath( $file ), $options );

		return $d;
	}

	/**
	 * @param string $path
	 * @param bool $sections
	 * @param bool $skipCustom - do not try to find overrides
	 *
	 * @return array
	 * @throws \Sobi\Error\Exception
	 */
	public function loadIniFile( string $path, bool $sections = true, bool $skipCustom = false, $mode = INI_SCANNER_NORMAL ): array
	{
		if ( !( $skipCustom ) ) {
			$customIni = $this->loadIniFile( $path . '_override', $sections, true, $mode );
			if ( $customIni && is_array( $customIni ) ) {
				return $customIni;
			}
		}
		$path .= '.ini';
		if ( !file_exists( $path ) || !is_readable( $path ) ) {
			// if we tried to load override, and it does not exist - do not rise any errors
			if ( !( $skipCustom ) ) {
				throw new Exception( sprintf( 'Cannot load file at %s', str_replace( JPATH_ROOT . '/', C::ES, $path ) ) );
			}
			else {
				return [];
			}
		}
		else {
			ob_start();
			$ini = parse_ini_file( $path, $sections, $mode );
			ob_end_clean();

			return is_array( $ini ) ? $ini : [];
		}
	}

	/**
	 * @param string $path
	 * @param array $values
	 *
	 * @return bool
	 * @throws \Sobi\Error\Exception
	 */
	public function writeIniFile( string $path, array $values ): bool
	{
		$data = null;
		foreach ( $values as $key => $val ) {
			if ( is_array( $val ) ) {
				$data[] = "[$key]";
				foreach ( $val as $skey => $sval ) {
					if ( is_array( $sval ) ) {
						foreach ( $sval as $_skey => $_sval ) {
							if ( is_numeric( $_skey ) ) {
								$data[] = $skey . '[] = ' . ( is_numeric( $_sval ) ? $_sval : ( ctype_upper( $_sval ) ? $_sval : '"' . $_sval . '"' ) );
							}
							else {
								$data[] = $skey . '[' . $_skey . '] = ' . ( is_numeric( $_sval ) ? $_sval : ( ctype_upper( $_sval ) ? $_sval : '"' . $_sval . '"' ) );
							}
						}
					}
					else {
						$data[] = $this->createValue( $skey, $sval );
					}
				}
			}
			else {
				$data[] = $this->createValue( $skey, $sval );
			}
			// empty line
			$data[] = null;
		}

		$data = implode( PHP_EOL, $data ) . PHP_EOL;

		return $this->write( $path, $data );
	}

	/**
	 * @param $skey
	 * @param $sval
	 *
	 * @return string
	 */
	protected function createValue( $skey, $sval ): string
	{
		/* check if indicator for boolean type is set */
		if ( strpos( $skey, 'bool.' ) === 0 ) {
			/* remove indicator */
			$skey = str_replace( 'bool.', '', $skey );
			/* convert 0/1 to false/true */
			$sval = $sval == 0 ? 'false' : 'true';
			$value = $skey . ' = ' . $sval;
		}
		else {
			$value = $skey . ' = ' . ( is_numeric( $sval ) ? $sval : ( ctype_upper( $sval ) ? $sval : '"' . $sval . '"' ) );
		}

		return $value;
	}
}