<commit_before><?php
namespace Concrete\Core\File;

use Carbon\Carbon;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Util\Debug;
use Doctrine\DBAL\Logging\EchoSQLLogger;
use FileSet;
use League\Flysystem\AdapterInterface;
use Loader;
use CacheLocal;
use Core;
use User;
use Events;
use Page;
use Database;
use \Concrete\Core\Attribute\Key as AttributeKey;
use \Concrete\Core\File\StorageLocation\StorageLocation;
use FileAttributeKey;
use PermissionKey;

/**
 * @Entity
 * @Table(name="Files")
 */
class File implements \Concrete\Core\Permission\ObjectInterface
{

    const CREATE_NEW_VERSION_THRESHOLD = 300;


    /**
     * @Id @Column(type="integer")
     * @GeneratedValue
     */
    protected $fID;

    /**
     * @Column(type="datetime")
     */
    protected $fDateAdded = null;

    /**
     * @Column(type="string")
     */
    protected $fPassword;

    /**
     * @OneToMany(targetEntity="Version", mappedBy="file", cascade={"persist"})
     * @JoinColumn(name="fID")
     */
    protected $versions;

    /**
     * @Column(type="boolean")
     */
    protected $fOverrideSetPermissions = false;

    /**
     * Originally placed on which page.
     * @Column(columnDefinition="integer unsigned")
     */
    protected $ocID = 0;

    /**
     * @Column(columnDefinition="integer unsigned")
     */
    protected $uID = 0;

    /**
     * @ManyToOne(targetEntity="\Concrete\Core\File\StorageLocation\StorageLocation")
     * @JoinColumn(name="fslID", referencedColumnName="fslID")
     **/
    protected $storageLocation;

    public function __construct()
    {
        $this->versions = new ArrayCollection();
    }

    /**
     * returns a file object for the given file ID
     * @param int $fID
     * @return File
     */
    public static function getByID($fID)
    {
        $db = Database::get();
        $em = $db->getEntityManager();
        return $em->find('\Concrete\Core\File\File', $fID);
    }

    /**
     * For all methods that file does not implement, we pass through to the currently active file version object
     */
    public function __call($nm, $a)
    {
        $fv = $this->getApprovedVersion();
        if(is_null($fv)) {
            return null;
        }
        return call_user_func_array(array($fv, $nm), $a);
    }

    public function getPermissionResponseClassName()
    {
        return '\\Concrete\\Core\\Permission\\Response\\FileResponse';
    }

    public function getPermissionAssignmentClassName()
    {
        return '\\Concrete\\Core\\Permission\\Assignment\\FileAssignment';
    }

    public function getPermissionObjectKeyCategoryHandle()
    {
        return 'file';
    }

    public function getPermissionObjectIdentifier()
    {
        return $this->getFileID();
    }

    public function getPassword()
    {
        return <PASSWORD>;
    }

    public function getStorageLocationID()
    {
        return $this->storageLocation;
    }

    /**
     * @return \Concrete\Core\File\StorageLocation\StorageLocation
     */
    public function getFileStorageLocationObject()
    {
        return $this->storageLocation;
    }

    /**
     * @return array \Concrete\Core\File\Version
     */
    public function getFileVersions()
    {
        return $this->versions;
    }

    /**
     * Reindex the attributes on this file.
     * @return void
     */
    public function reindex()
    {
        $attribs = FileAttributeKey::getAttributes(
            $this->getFileID(),
            $this->getFileVersionID(),
            'getSearchIndexValue'
        );
        $db = Loader::db();

        $db->Execute('delete from FileSearchIndexAttributes where fID = ?', array($this->getFileID()));
        $searchableAttributes = array('fID' => $this->getFileID());

        $key = new FileAttributeKey();
        $key->reindex('FileSearchIndexAttributes', $searchableAttributes, $attribs);
    }

    public static function getRelativePathFromID($fID)
    {
        $path = CacheLocal::getEntry('file_relative_path', $fID);
        if ($path != false) {
            return $path;
        }

        $f = static::getByID($fID);
        $path = $f->getRelativePath();

        CacheLocal::set('file_relative_path', $fID, $path);
        return $path;
    }

    protected function save()
    {
        $em = Database::get()->getEntityManager();
        $em->persist($this);
        $em->flush();
    }

    public function setFileStorageLocation(StorageLocation $newLocation)
    {
        $fh = Loader::helper('concrete/file');
        $currentLocation = $this->getFileStorageLocationObject();
        $currentFilesystem = $currentLocation->getFileSystemObject();

        $newFileSystem = $newLocation->getFileSystemObject();

        $list = $this->getVersionList();
        foreach ($list as $fv) {
            $contents = $fv->getFileContents();
            $newFileSystem->put($fh->prefix($fv->getPrefix(), $fv->getFilename()), $contents);
            $currentFilesystem->delete($fh->prefix($fv->getPrefix(), $fv->getFilename()));
        }

        $this->location = $newLocation;
        $this->save();
    }

    public function setPassword($pw)
    {

        $fe = new \Concrete\Core\File\Event\FileWithPassword($this);
        $fe->setFilePassword($pw);
        Events::dispatch('on_file_set_password', $fe);<commit_msg>Fixing file storage location data loss when saving form with same location<commit_after><?php
namespace Concrete\Core\File;

use Carbon\Carbon;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Util\Debug;
use Doctrine\DBAL\Logging\EchoSQLLogger;
use FileSet;
use League\Flysystem\AdapterInterface;
use Loader;
use CacheLocal;
use Core;
use User;
use Events;
use Page;
use Database;
use \Concrete\Core\Attribute\Key as AttributeKey;
use \Concrete\Core\File\StorageLocation\StorageLocation;
use FileAttributeKey;
use PermissionKey;

/**
 * @Entity
 * @Table(name="Files")
 */
class File implements \Concrete\Core\Permission\ObjectInterface
{

    const CREATE_NEW_VERSION_THRESHOLD = 300;


    /**
     * @Id @Column(type="integer")
     * @GeneratedValue
     */
    protected $fID;

    /**
     * @Column(type="datetime")
     */
    protected $fDateAdded = null;

    /**
     * @Column(type="string")
     */
    protected $fPassword;

    /**
     * @OneToMany(targetEntity="Version", mappedBy="file", cascade={"persist"})
     * @JoinColumn(name="fID")
     */
    protected $versions;

    /**
     * @Column(type="boolean")
     */
    protected $fOverrideSetPermissions = false;

    /**
     * Originally placed on which page.
     * @Column(columnDefinition="integer unsigned")
     */
    protected $ocID = 0;

    /**
     * @Column(columnDefinition="integer unsigned")
     */
    protected $uID = 0;

    /**
     * @ManyToOne(targetEntity="\Concrete\Core\File\StorageLocation\StorageLocation")
     * @JoinColumn(name="fslID", referencedColumnName="fslID")
     **/
    protected $storageLocation;

    public function __construct()
    {
        $this->versions = new ArrayCollection();
    }

    /**
     * returns a file object for the given file ID
     * @param int $fID
     * @return File
     */
    public static function getByID($fID)
    {
        $db = Database::get();
        $em = $db->getEntityManager();
        return $em->find('\Concrete\Core\File\File', $fID);
    }

    /**
     * For all methods that file does not implement, we pass through to the currently active file version object
     */
    public function __call($nm, $a)
    {
        $fv = $this->getApprovedVersion();
        if(is_null($fv)) {
            return null;
        }
        return call_user_func_array(array($fv, $nm), $a);
    }

    public function getPermissionResponseClassName()
    {
        return '\\Concrete\\Core\\Permission\\Response\\FileResponse';
    }

    public function getPermissionAssignmentClassName()
    {
        return '\\Concrete\\Core\\Permission\\Assignment\\FileAssignment';
    }

    public function getPermissionObjectKeyCategoryHandle()
    {
        return 'file';
    }

    public function getPermissionObjectIdentifier()
    {
        return $this->getFileID();
    }

    public function getPassword()
    {
        return $this->fPassword;
    }

    public function getStorageLocationID()
    {
        return $this->storageLocation;
    }

    /**
     * @return \Concrete\Core\File\StorageLocation\StorageLocation
     */
    public function getFileStorageLocationObject()
    {
        return $this->storageLocation;
    }

    /**
     * @return array \Concrete\Core\File\Version
     */
    public function getFileVersions()
    {
        return $this->versions;
    }

    /**
     * Reindex the attributes on this file.
     * @return void
     */
    public function reindex()
    {
        $attribs = FileAttributeKey::getAttributes(
            $this->getFileID(),
            $this->getFileVersionID(),
            'getSearchIndexValue'
        );
        $db = Loader::db();

        $db->Execute('delete from FileSearchIndexAttributes where fID = ?', array($this->getFileID()));
        $searchableAttributes = array('fID' => $this->getFileID());

        $key = new FileAttributeKey();
        $key->reindex('FileSearchIndexAttributes', $searchableAttributes, $attribs);
    }

    public static function getRelativePathFromID($fID)
    {
        $path = CacheLocal::getEntry('file_relative_path', $fID);
        if ($path != false) {
            return $path;
        }

        $f = static::getByID($fID);
        $path = $f->getRelativePath();

        CacheLocal::set('file_relative_path', $fID, $path);
        return $path;
    }

    protected function save()
    {
        $em = Database::get()->getEntityManager();
        $em->persist($this);
        $em->flush();
    }

    public function setFileStorageLocation(StorageLocation $newLocation)
    {
        $fh = Loader::helper('concrete/file');
        $currentLocation = $this->getFileStorageLocationObject();
        if ($newLocation->getID() == $currentLocation->getID()) {
            return false;
        }

        $currentFilesystem = $currentLocation->getFileSystemObject();

        $newFileSystem = $newLocation->getFileSystemObject();

        $list = $this->getVersionList();
        foreach ($list as $fv) {
            $contents = $fv->getFileContents();
            $newFileSystem->put($fh->prefix($fv->getPrefix(), $fv->getFilename()), $contents);
            $currentFilesystem->delete($fh->prefix($fv->getPrefix(), $fv->getFilename()));
        }

        $this->location = $newLocation;
        $this->save();
    }

    public function setPassword($pw)
    {

        $fe = new \Concrete\Core\File\Event\FileWithPassword($this);
        $fe->setFilePassword($pw);
        Events::dispatch('on_file_set_password', $fe);
{'fraction_non_alphanumeric': 0.13947465778764337, 'fraction_numerical': 0.000924898261191269, 'mean_word_length': 2.582836315440689, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2206326', 'n_tokens_mistral': 3203, 'n_tokens_neox': 3095, 'n_words': 605}