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

use Carbon\Carbon;
use Concrete\Core\Attribute\Value\FileValue as FileAttributeValue;
use Concrete\Core\File\Exception\InvalidDimensionException;
use Concrete\Core\File\Image\Thumbnail\Thumbnail;
use Concrete\Core\File\Image\Thumbnail\Type\Type;
use Concrete\Core\File\Image\Thumbnail\Type\Version as ThumbnailTypeVersion;
use Concrete\Core\File\Type\TypeList as FileTypeList;
use Concrete\Flysystem\AdapterInterface;
use Concrete\Flysystem\FileNotFoundException;
use Core;
use Events;
use FileAttributeKey;
use Imagine\Image\ImageInterface;
use Loader;
use Page;
use Permissions;
use stdClass;
use User;
use View;

/**
 * @Entity
 * @Table(name="FileVersions")
 */
class Version
{

    const UT_REPLACE_FILE = 1;
    const UT_TITLE = 2;
    const UT_DESCRIPTION = 3;
    const UT_TAGS = 4;
    const UT_EXTENDED_ATTRIBUTE = 5;
    /**
     * /* @Id
     * @ManyToOne(targetEntity="File", inversedBy="versions")
     * @JoinColumn(name="fID", referencedColumnName="fID")
     * @var \Concrete\Core\File\File
     */
    protected $file;
    /** @Id
     * @Column(type="integer")
     */
    protected $fvID = 0;
    /**
     * @Column(type="string")
     */
    protected $fvFilename = null;
    /**
     * @Column(type="string")
     */
    protected $fvPrefix;
    /**
     * @Column(type="datetime")
     */
    protected $fvDateAdded;
    /**
     * @Column(type="datetime")
     */
    protected $fvActivateDateTime;
    /**
     * @Column(type="boolean")
     */
    protected $fvIsApproved = false;
    /**
     * @Column(type="integer")
     */
    protected $fvAuthorUID = 0;
    /**
     * @Column(type="bigint")
     */
    protected $fvSize = 0;
    /**
     * @Column(type="integer")
     */
    protected $fvApproverUID = 0;
    /**
     * @Column(type="string")
     */
    protected $fvTitle = null;
    /**
     * @Column(type="text")
     */
    protected $fvDescription = null;
    /**
     * @Column(type="string")
     */
    protected $fvExtension = null;
    /**
     * @Column(type="integer")
     */
    protected $fvType = 0;
    /**
     * @Column(type="text")
     */
    protected $fvTags = null;
    /**
     * @Column(type="boolean")
     */
    protected $fvHasListingThumbnail = false;
    /**
     * @Column(type="boolean")
     */
    protected $fvHasDetailThumbnail = false;

    // Update type constants
    protected $attributes = array();

    public static function add(\Concrete\Core\File\File $file, $filename, $prefix, $data = array())
    {
        $u = new User();
        $uID = (isset($data['uID']) && $data['uID'] > 0) ? $data['uID'] : $u->getUserID();

        if ($uID < 1) {
            $uID = 0;
        }

        $fvTitle = (isset($data['fvTitle'])) ? $data['fvTitle'] : '';
        $fvDescription = (isset($data['fvDescription'])) ? $data['fvDescription'] : '';
        $fvTags = (isset($data['fvTags'])) ? Version::cleanTags($data['fvTags']) : '';
        $fvIsApproved = (isset($data['fvIsApproved'])) ? $data['fvIsApproved'] : '1';

        $db = Loader::db();
        $dh = Loader::helper('date');
        $date = new Carbon($dh->getOverridableNow());

        $fv = new static();
        $fv->fvFilename = $filename;
        $fv->fvPrefix = $prefix;
        $fv->fvDateAdded = $date;
        $fv->fvIsApproved = (bool)$fvIsApproved;
        $fv->fvApproverUID = $uID;
        $fv->fvAuthorUID = $uID;
        $fv->fvActivateDateTime = $date;
        $fv->fvTitle = $fvTitle;
        $fv->fvTags = $fvTags;
        $fv->file = $file;
        $fv->fvID = 1;

        $em = Loader::db()->getEntityManager();
        $em->persist($fv);
        $em->flush();

        $fve = new \Concrete\Core\File\Event\FileVersion($fv);
        Events::dispatch('on_file_version_add', $fve);

        return $fv;
    }

    public static function cleanTags($tagsStr)
    {
        $tagsArray = explode("\n", str_replace(array("\r", ","), "\n", $tagsStr));
        $cleanTags = array();
        foreach ($tagsArray as $tag) {
            if (!strlen(trim($tag))) {
                continue;
            }
            $cleanTags[] = trim($tag);
        }
        //the leading and trailing line break char is for searching: fvTag like %\ntag\n%
        return "\n" . join("\n", $cleanTags) . "\n";
    }

    public function getPrefix()
    {
        return $this->fvPrefix;
    }

    public function isApproved()
    {
        return $this->fvIsApproved;
    }

    public function getTagsList()
    {
        $tags = explode("\n", str_replace("\r", "\n", trim($this->getTags())));
        $clean_tags = array();
        foreach ($tags as $tag) {
            if (strlen(trim($tag))) {
                $clean_tags[] = trim($tag);
            }
        }
        return $clean_tags;
    }

    public function getTags()
    {
        return $this->fvTags;
    }

    public function setAttribute($ak, $value)
    {
        if (!is_object($ak)) {
            $ak = FileAttributeKey::getByHandle($ak);
        }
        $ak->setAttribute($this, $value);
        $fo = $this->getFile();
        $fo->reindex();
        unset($ak);
    }

    /**
     * returns the File object associated with this FileVersion object
     *
     * @return \File
     */
    public function getFile()
    {
        return $this->file;
    }

    public function setFile(\Concrete\Core\File\File $file)
    {
        $this->file = $file;
    }

    public function clearAttribute($ak)
    {
        $db = Loader::db();
        $cav = $this->getAttributeValueObject($ak);
        if (is_object($cav)) {
            $cav->delete();
        }
        $fo = $this->getFile();
        $fo->reindex();
    }

    public function getAttributeValueObject($ak, $createIfNotFound = false)
    {
        $db = Loader::db();
        $av = false;
        $v = array($this->getFileID(), $this->getFileVersionID(), $ak->getAttributeKeyID());
        $avID = $db->GetOne("SELECT avID FROM FileAttributeValues WHERE fID = ? AND fvID = ? AND akID = ?", $v);
        if ($avID > 0) {
            $av = FileAttributeValue::getByID($avID);
            if (is_object($av)) {
                $av->setFile($this->getFile());
                $av->setAttributeKey($ak);
            }
        }

        if ($createIfNotFound) {
            $cnt = 0;

            // Is this avID in use ?
            if (is_object($av)) {
                $cnt = $db->GetOne(
                    "SELECT count(avID) FROM FileAttributeValues WHERE avID = ?",
                    $av->getAttributeValueID()
                );
            }

            if ((!is_object($av)) || ($cnt > 1)) {
                $newAV = $ak->addAttributeValue();
                $av = FileAttributeValue::getByID($newAV->getAttributeValueID());
                $av->setFile($this->getFile());
            }
        }

        return $av;
    }

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

    //returns an array of tags, instead of a string

    public function getFileVersionID()
    {
        return $this->fvID;
    }

    /**
     * Removes a version of a file. Note, does NOT remove the file because we don't know where the file might elsewhere be used/referenced.
     */
    public function delete($deleteFilesAndThumbnails = false)
    {

        $db = Loader::db();
        $em = $db->getEntityManager();
        $em->remove($this);
        $em->flush();

        $db->Execute("DELETE FROM FileAttributeValues WHERE fID = ? AND fvID = ?", array($this->fID, $this->fvID));
        $db->Execute("DELETE FROM FileVersionLog WHERE fID = ? AND fvID = ?", array($this->fID, $this->fvID));

        $types = Type::getVersionList();

        if ($deleteFilesAndThumbnails) {
            try {
                foreach ($types as $type) {
                    $this->deleteThumbnail($type);
                }

                $fsl = $this->getFile()->getFileStorageLocationObject()->getFileSystemObject();
                $fre = $this->getFileResource();
                if ($fsl->has($fre->getPath())) {
                    $fsl->delete($fre->getPath());
                }
            } catch (FileNotFoundException $e) {
            }
        }
    }

    /**
     * Deletes the thumbnail for the particular thumbnail type.
     */
    public function deleteThumbnail($type)
    {
        if (!($type instanceof ThumbnailTypeVersion)) {
            $type = ThumbnailTypeVersion::getByHandle($type);
        }
        $fsl = $this->getFile()->getFileStorageLocationObject()->getFileSystemObject();
        $path = $type->getFilePath($this);
        if ($fsl->has($path)) {
            $fsl->delete($path);<commit_msg>Fix file version delete bug<commit_after><?php
namespace Concrete\Core\File;

use Carbon\Carbon;
use Concrete\Core\Attribute\Value\FileValue as FileAttributeValue;
use Concrete\Core\File\Exception\InvalidDimensionException;
use Concrete\Core\File\Image\Thumbnail\Thumbnail;
use Concrete\Core\File\Image\Thumbnail\Type\Type;
use Concrete\Core\File\Image\Thumbnail\Type\Version as ThumbnailTypeVersion;
use Concrete\Core\File\Type\TypeList as FileTypeList;
use Concrete\Flysystem\AdapterInterface;
use Concrete\Flysystem\FileNotFoundException;
use Core;
use Events;
use FileAttributeKey;
use Imagine\Image\ImageInterface;
use Loader;
use Page;
use Permissions;
use stdClass;
use User;
use View;

/**
 * @Entity
 * @Table(name="FileVersions")
 */
class Version
{

    const UT_REPLACE_FILE = 1;
    const UT_TITLE = 2;
    const UT_DESCRIPTION = 3;
    const UT_TAGS = 4;
    const UT_EXTENDED_ATTRIBUTE = 5;
    /**
     * /* @Id
     * @ManyToOne(targetEntity="File", inversedBy="versions")
     * @JoinColumn(name="fID", referencedColumnName="fID")
     * @var \Concrete\Core\File\File
     */
    protected $file;
    /** @Id
     * @Column(type="integer")
     */
    protected $fvID = 0;
    /**
     * @Column(type="string")
     */
    protected $fvFilename = null;
    /**
     * @Column(type="string")
     */
    protected $fvPrefix;
    /**
     * @Column(type="datetime")
     */
    protected $fvDateAdded;
    /**
     * @Column(type="datetime")
     */
    protected $fvActivateDateTime;
    /**
     * @Column(type="boolean")
     */
    protected $fvIsApproved = false;
    /**
     * @Column(type="integer")
     */
    protected $fvAuthorUID = 0;
    /**
     * @Column(type="bigint")
     */
    protected $fvSize = 0;
    /**
     * @Column(type="integer")
     */
    protected $fvApproverUID = 0;
    /**
     * @Column(type="string")
     */
    protected $fvTitle = null;
    /**
     * @Column(type="text")
     */
    protected $fvDescription = null;
    /**
     * @Column(type="string")
     */
    protected $fvExtension = null;
    /**
     * @Column(type="integer")
     */
    protected $fvType = 0;
    /**
     * @Column(type="text")
     */
    protected $fvTags = null;
    /**
     * @Column(type="boolean")
     */
    protected $fvHasListingThumbnail = false;
    /**
     * @Column(type="boolean")
     */
    protected $fvHasDetailThumbnail = false;

    // Update type constants
    protected $attributes = array();

    public static function add(\Concrete\Core\File\File $file, $filename, $prefix, $data = array())
    {
        $u = new User();
        $uID = (isset($data['uID']) && $data['uID'] > 0) ? $data['uID'] : $u->getUserID();

        if ($uID < 1) {
            $uID = 0;
        }

        $fvTitle = (isset($data['fvTitle'])) ? $data['fvTitle'] : '';
        $fvDescription = (isset($data['fvDescription'])) ? $data['fvDescription'] : '';
        $fvTags = (isset($data['fvTags'])) ? Version::cleanTags($data['fvTags']) : '';
        $fvIsApproved = (isset($data['fvIsApproved'])) ? $data['fvIsApproved'] : '1';

        $db = Loader::db();
        $dh = Loader::helper('date');
        $date = new Carbon($dh->getOverridableNow());

        $fv = new static();
        $fv->fvFilename = $filename;
        $fv->fvPrefix = $prefix;
        $fv->fvDateAdded = $date;
        $fv->fvIsApproved = (bool)$fvIsApproved;
        $fv->fvApproverUID = $uID;
        $fv->fvAuthorUID = $uID;
        $fv->fvActivateDateTime = $date;
        $fv->fvTitle = $fvTitle;
        $fv->fvTags = $fvTags;
        $fv->file = $file;
        $fv->fvID = 1;

        $em = Loader::db()->getEntityManager();
        $em->persist($fv);
        $em->flush();

        $fve = new \Concrete\Core\File\Event\FileVersion($fv);
        Events::dispatch('on_file_version_add', $fve);

        return $fv;
    }

    public static function cleanTags($tagsStr)
    {
        $tagsArray = explode("\n", str_replace(array("\r", ","), "\n", $tagsStr));
        $cleanTags = array();
        foreach ($tagsArray as $tag) {
            if (!strlen(trim($tag))) {
                continue;
            }
            $cleanTags[] = trim($tag);
        }
        //the leading and trailing line break char is for searching: fvTag like %\ntag\n%
        return "\n" . join("\n", $cleanTags) . "\n";
    }

    public function getPrefix()
    {
        return $this->fvPrefix;
    }

    public function isApproved()
    {
        return $this->fvIsApproved;
    }

    public function getTagsList()
    {
        $tags = explode("\n", str_replace("\r", "\n", trim($this->getTags())));
        $clean_tags = array();
        foreach ($tags as $tag) {
            if (strlen(trim($tag))) {
                $clean_tags[] = trim($tag);
            }
        }
        return $clean_tags;
    }

    public function getTags()
    {
        return $this->fvTags;
    }

    public function setAttribute($ak, $value)
    {
        if (!is_object($ak)) {
            $ak = FileAttributeKey::getByHandle($ak);
        }
        $ak->setAttribute($this, $value);
        $fo = $this->getFile();
        $fo->reindex();
        unset($ak);
    }

    /**
     * returns the File object associated with this FileVersion object
     *
     * @return \File
     */
    public function getFile()
    {
        return $this->file;
    }

    public function setFile(\Concrete\Core\File\File $file)
    {
        $this->file = $file;
    }

    public function clearAttribute($ak)
    {
        $db = Loader::db();
        $cav = $this->getAttributeValueObject($ak);
        if (is_object($cav)) {
            $cav->delete();
        }
        $fo = $this->getFile();
        $fo->reindex();
    }

    public function getAttributeValueObject($ak, $createIfNotFound = false)
    {
        $db = Loader::db();
        $av = false;
        $v = array($this->getFileID(), $this->getFileVersionID(), $ak->getAttributeKeyID());
        $avID = $db->GetOne("SELECT avID FROM FileAttributeValues WHERE fID = ? AND fvID = ? AND akID = ?", $v);
        if ($avID > 0) {
            $av = FileAttributeValue::getByID($avID);
            if (is_object($av)) {
                $av->setFile($this->getFile());
                $av->setAttributeKey($ak);
            }
        }

        if ($createIfNotFound) {
            $cnt = 0;

            // Is this avID in use ?
            if (is_object($av)) {
                $cnt = $db->GetOne(
                    "SELECT count(avID) FROM FileAttributeValues WHERE avID = ?",
                    $av->getAttributeValueID()
                );
            }

            if ((!is_object($av)) || ($cnt > 1)) {
                $newAV = $ak->addAttributeValue();
                $av = FileAttributeValue::getByID($newAV->getAttributeValueID());
                $av->setFile($this->getFile());
            }
        }

        return $av;
    }

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

    //returns an array of tags, instead of a string

    public function getFileVersionID()
    {
        return $this->fvID;
    }

    /**
     * Removes a version of a file. Note, does NOT remove the file because we don't know where the file might elsewhere be used/referenced.
     */
    public function delete($deleteFilesAndThumbnails = false)
    {

        $db = Loader::db();

        $db->Execute("DELETE FROM FileAttributeValues WHERE fID = ? AND fvID = ?", array($this->getFileID(), $this->fvID));
        $db->Execute("DELETE FROM FileVersionLog WHERE fID = ? AND fvID = ?", array($this->getFileID(), $this->fvID));

        $types = Type::getVersionList();

        if ($deleteFilesAndThumbnails) {
            try {
                foreach ($types as $type) {
                    $this->deleteThumbnail($type);
                }

                $fsl = $this->getFile()->getFileStorageLocationObject()->getFileSystemObject();
                $fre = $this->getFileResource();
                if ($fsl->has($fre->getPath())) {
                    $fsl->delete($fre->getPath());
                }
            } catch (FileNotFoundException $e) {
            }
        }

        $em = $db->getEntityManager();
        $em->remove($this);
        $em->flush();
    }

    /**
     * Deletes the thumbnail for the particular thumbnail type.
     */
    public function deleteThumbnail($type)
    {
        if (!($type instanceof ThumbnailTypeVersion)) {
            $type = ThumbnailTypeVersion::getByHandle($type);
        }
        $fsl = $this->getFile()->getFileStorageLocationObject()->getFileSystemObject();
        $path = $type->getFilePath($this);
        if ($fsl->has($path)) {
            $fsl->delete($path);
{'fraction_non_alphanumeric': 0.16295015845577643, 'fraction_numerical': 0.002074330164217805, 'mean_word_length': 2.064265536723164, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 147, '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': '7038559', 'n_tokens_mistral': 5592, 'n_tokens_neox': 5316, 'n_words': 1049}