<?php
/**
 * woobooking! Content Management System
 *
 * Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 */

namespace WpBookingHotel\Filesystem;
defined('_WPBOOKINGHOTEL_EXEC') or die;



use WpBookingHotel\Factory;
use WpBookingHotel\Filesystem\Wrapper\PathWrapper;
use WpBookingHotel\Filesystem\Wrapper\FolderWrapper;
/**
 * A File handling class
 *

 */
class File
{
    /**
     * Gets the extension of a file name
     *
     * @param string $file The file name
     *
     * @return  string  The file extension
     *
     * @since   1.7.0
     */
    public static function getExt($file)
    {
        $dot = strrpos($file, '.');

        if ($dot === false) {
            return '';
        }

        return (string)substr($file, $dot + 1);
    }

    /**
     * Strips the last extension off of a file name
     *
     * @param string $file The file name
     *
     * @return  string  The file name without the extension
     *
     * @since   1.7.0
     */
    public static function stripExt($file)
    {
        return preg_replace('#\.[^.]*$#', '', $file);
    }

    /**
     * Makes file name safe to use
     *
     * @param string $file The name of the file [not full path]
     *
     * @return  string  The sanitised string
     *
     * @since   1.7.0
     */
    public static function makeSafe($file)
    {
        // Remove any trailing dots, as those aren't ever valid file names.
        $file = rtrim($file, '.');

        $regex = array('#(\.){2,}#', '#[^A-Za-z0-9\.\_\- ]#', '#^\.#');

        return trim(preg_replace($regex, '', $file));
    }

    /**
     * Copies a file
     *
     * @param string $src The path to the source file
     * @param string $dest The path to the destination file
     * @param string $path An optional base path to prefix to the file names
     * @param boolean $use_streams True to use streams
     *
     * @return  boolean  True on success
     *
     * @since   1.7.0
     */
    public static function copy($src, $dest, $path = null, $use_streams = false)
    {
        $pathObject = new PathWrapper;
        // Prepend a base path if it exists
        if ($path)
        {
            $src = $pathObject->clean($path . '/' . $src);
            $dest = $pathObject->clean($path . '/' . $dest);
        }
        // Check src path
        if (!is_readable($src))
        {
            return false;
        }

        if (!@ copy($src, $dest))
        {
            return false;
        }
        return true;
    }

    /**
     * Delete a file or array of files
     *
     * @param mixed $file The file name or an array of file names
     *
     * @return  boolean  True on success
     *
     * @since   1.7.0
     */
    public static function delete($file)
    {
        $pathObject = new PathWrapper;

        if (is_array($file))
        {
            $files = $file;
        }
        else
        {
            $files[] = $file;
        }

        foreach ($files as $file)
        {
            $file = $pathObject->clean($file);

            if (!is_file($file))
            {
                continue;
            }

            // Try making the file writable first. If it's read-only, it can't be deleted
            // on Windows, even if the parent folder is writable
            chmod($file, 0777);
            // In case of restricted permissions we zap it one way or the other
            // as long as the owner is either the webserver or the ftp
            if (unlink($file))
            {
                // Do nothing
            }
        }

        return true;
    }

    /**
     * Moves a file
     *
     * @param string $src The path to the source file
     * @param string $dest The path to the destination file
     * @return  boolean  True on success
     *
     * @since   1.7.0
     */
    public static function upload($src, $dest)
    {

        // Ensure that the path is valid and clean
        $pathObject = new PathWrapper;
        $dest = $pathObject->clean($dest);

        // Create the destination directory if it does not exist
        $baseDir = dirname($dest);

        if (!file_exists($baseDir))
        {
            $folderObject = new FolderWrapper;
            $folderObject->create($baseDir);
        }
        if (is_writeable($baseDir) && move_uploaded_file($src, $dest))
        {
            // Short circuit to prevent file permission errors
            if ($pathObject->setPermissions($dest))
            {
                $ret = true;
            }

        }
        return  $ret;

    }

    /**
     * Read the contents of a file
     *
     * @param string $filename The full file path
     *
     * @return  mixed  Returns file contents or boolean False if failed
     *
     * @since   1.7.0
     */
    public static function read($filename)
    {

        global $wp_filesystem;
        if (empty($wp_filesystem)) {
            require_once (ABSPATH . '/wp-admin/includes/file.php');
            WP_Filesystem();
        }
        $data =  $wp_filesystem->get_contents($filename);

        return $data;
    }


    /**
     * Write contents to a file
     *
     * @param string $file The full file path
     * @param string $buffer The buffer to write
     * @param boolean $use_streams Use streams
     *
     * @return  boolean  True on success
     *
     * @since   1.7.0
     */
    public static function write($file, $buffer, $use_streams = false)
    {
        // If the destination directory doesn't exist we need to create it
        if (!file_exists(dirname($file)))
        {
            $folderObject = new FolderWrapper;

            if ($folderObject->create(dirname($file)) == false)
            {
                return false;
            }
        }
        global $wp_filesystem;
        if (empty($wp_filesystem)) {
            require_once (ABSPATH . '/wp-admin/includes/file.php');
            WP_Filesystem();
        }
        $pathObject = new PathWrapper;
        $file = $pathObject->clean($file);
        return $wp_filesystem->put_contents($file,$buffer);

    }

    /**
     * Append contents to a file
     *
     * @param string $file The full file path
     * @param string $buffer The buffer to write
     * @param boolean $use_streams Use streams
     *
     * @return  boolean  True on success
     *
     * @since   3.6.0
     */
    public static function append($file, $buffer, $use_streams = false)
    {
        // If the file doesn't exist, just write instead of append
        if (!file_exists($file))
        {
            return self::write($file, $buffer, $use_streams);
        }
        $file = Path::clean($file);
        //TODO fix else
        $ret=true;
        return $ret;
    }


    /**
     * Wrapper for the standard file_exists function
     *
     * @param string $file File path
     *
     * @return  boolean  True if path is a file
     *
     * @since   1.7.0
     */
    public static function exists($file)
    {
        $pathObject = new PathWrapper;

        return is_file($pathObject->clean($file));
    }

    /**
     * Returns the name, without any path.
     *
     * @param string $file File path
     *
     * @return  string  filename
     *
     * @since   1.7.0
     * @deprecated  4.0 - Use basename() instead.
     */
    public static function getName($file)
    {

        // Convert back slashes to forward slashes
        $file = str_replace('\\', '/', $file);
        $slash = strrpos($file, '/');

        if ($slash !== false) {
            return substr($file, $slash + 1);
        } else {
            return $file;
        }
    }
}
