<commit_before><?php
namespace Concrete\Package\CommunityTranslation\Src\Service;

use Concrete\Core\Application\Application;
use Concrete\Package\CommunityTranslation\Src\Locale\Locale;
use Concrete\Package\CommunityTranslation\Src\Translatable\Translatable;
use Concrete\Package\CommunityTranslation\Src\Translatable\Comment\Comment;

class Editor implements \Concrete\Core\Application\ApplicationAwareInterface
{
    /**
     * Maximum number of translation suggestions.
     *
     * @var int
     */
    const MAX_SUGGESTIONS = 15;

    /**
     * Maximum number of glossary terms to show in the editor.
     *
     * @var int
     */
    const MAX_GLOSSARY_ENTRIES = 15;

    /**
     * The application object.
     *
     * @var Application
     */
    protected $app;

    /**
     * Set the application object.
     *
     * @param Application $application
     */
    public function setApplication(Application $app)
    {
        $this->app = $app;
    }

    /**
     * Returns the data to be used in the editor when editing a string.
     *
     * @param Locale $locale The current editor locale.
     * @param Translatable $translatable The source string that's being translated.
     * @param bool $initial Set to true when a string is first loaded, false after it has been saved.
     *
     * @return array
     */
    public function getTranslatableData(Locale $locale, Translatable $translatable, $initial)
    {
        $result = array();
        $result['translations'] = $this->getTranslations($locale, $translatable);
        if ($initial) {
            $result['comments'] = $this->getComments($locale, $translatable);
            $result['suggestions'] = $this->getSuggestions($locale, $translatable);
            $result['glossary'] = $this->getGlossaryTerms($locale, $translatable);
        }

        return $result;
    }

    /**
     * Search all the translations associated to a translatable string.
     *
     * @param Locale $locale
     * @param Translatable $translatable
     *
     * @return array
     */
    public function getTranslations(Locale $locale, Translatable $translatable)
    {
        $numPlurals = $locale->getPluralCount();

        $result = array();
        $translations = $this->app->make('community_translation/translation')->findBy(array('tTranslatable' => $translatable, 'tLocale' => $locale), array('tCreatedOn' => 'DESC'));
        foreach ($translations as $translation) {
            $texts = array();
            switch ($numPlurals) {
                case 6:
                    $texts[] = $translation->getText5();
                    /* @noinspection PhpMissingBreakStatementInspection */
                case 5:
                    $texts[] = $translation->getText4();
                    /* @noinspection PhpMissingBreakStatementInspection */
                case 4:
                    $texts[] = $translation->getText3();
                    /* @noinspection PhpMissingBreakStatementInspection */
                case 3:
                    $texts[] = $translation->getText2();
                    /* @noinspection PhpMissingBreakStatementInspection */
                case 2:
                    $texts[] = $translation->getText1();
                    /* @noinspection PhpMissingBreakStatementInspection */
                case 1:
                default:
                    $texts[] = $translation->getText0();
                    break;
            }
            $item = array(
                'id' => $translation->getID(),
                'created' => $translation->getCreatedOn(),
                'createdBy' => $translation->getCreatedBy(),
                'current' => $translation->isCurrent(),
                'currentSince' => $translation->isCurrentSince(),
                'reviewed' => $translation->isReviewed(),
                'texts' => array_reverse($texts),
            );
        }
        $rs->closeCursor();

        return $result;
    }

    /**
     * Get the comments associated to a translatable strings.
     *
     * @param Locale $locale
     * @param Translatable $translatable
     */
    public function getComments(Locale $locale, Translatable $translatable, Comment $parentComment = null)
    {
        $repo = $this->app->make('community_translation/translatable/comment');
        if ($parentComment === null) {
            $comments = $repo->findBy(
                array(
                    'tcTranslatable' => $translatable,
                    'tcParentComment' => null,
                    '$or' => array(
                        array('tcLocale' => $locale),
                        array('tcLocale' => null),
                    ),
                ),
                array('tcPostedOn' => 'ASC')
            );
        } else {
            $comments = $repo->findBy(
                array('tcParentComment' => $parentComment),
                array('tcPostedOn' => 'ASC')
            );
        }
        $result = array();
        foreach ($comments as $comment) {
            $result[] = array(
                'id' => $comment->getID(),
                'date' => $comment->getPostedOn(),
                'by' => $comment->getPostedBy(),
                'text' => $comment->getText(),
                'childComments' => $this->getComments($locale, $translatable, $comment),
            );
        }

        return $result;
    }

    /**
     * Search for similar translations.
     *
     * @param Locale $locale
     * @param Translatable $translatable
     *
     * @return array
     */
    public function getSuggestions(Locale $locale, Translatable $translatable)
    {
        $result = array();
        $connection = $this->app->make('community_translation/em')->getConnection();
        $rs = $connection->executeQuery(
            '
                select
                    Translatables.tText,
                    Translations.tText0,
                    match(Translatables.tText) against (:search in natural language mode) as relevance
                from
                    Translations
                    inner join Translatables on Translations.tTranslatable = Translatables.tID and 1 = Translations.tCurrent and :locale = Translations.tLocale
                where
                    Translatables.tID <> :currentTranslatableID
                    and length(Translatables.tText) between :minLength and :axLength
                having<commit_msg>Bug fixes<commit_after><?php
namespace Concrete\Package\CommunityTranslation\Src\Service;

use Concrete\Core\Application\Application;
use Concrete\Package\CommunityTranslation\Src\Locale\Locale;
use Concrete\Package\CommunityTranslation\Src\Translatable\Translatable;
use Concrete\Package\CommunityTranslation\Src\Translatable\Comment\Comment;

class Editor implements \Concrete\Core\Application\ApplicationAwareInterface
{
    /**
     * Maximum number of translation suggestions.
     *
     * @var int
     */
    const MAX_SUGGESTIONS = 15;

    /**
     * Maximum number of glossary terms to show in the editor.
     *
     * @var int
     */
    const MAX_GLOSSARY_ENTRIES = 15;

    /**
     * The application object.
     *
     * @var Application
     */
    protected $app;

    /**
     * Set the application object.
     *
     * @param Application $application
     */
    public function setApplication(Application $app)
    {
        $this->app = $app;
    }

    /**
     * Returns the data to be used in the editor when editing a string.
     *
     * @param Locale $locale The current editor locale.
     * @param Translatable $translatable The source string that's being translated.
     * @param bool $initial Set to true when a string is first loaded, false after it has been saved.
     *
     * @return array
     */
    public function getTranslatableData(Locale $locale, Translatable $translatable, $initial)
    {
        $result = array();
        $result['translations'] = $this->getTranslations($locale, $translatable);
        if ($initial) {
            $result['comments'] = $this->getComments($locale, $translatable);
            $result['suggestions'] = $this->getSuggestions($locale, $translatable);
            $result['glossary'] = $this->getGlossaryTerms($locale, $translatable);
        }

        return $result;
    }

    /**
     * Search all the translations associated to a translatable string.
     *
     * @param Locale $locale
     * @param Translatable $translatable
     *
     * @return array
     */
    public function getTranslations(Locale $locale, Translatable $translatable)
    {
        $numPlurals = $locale->getPluralCount();

        $result = array();
        $translations = $this->app->make('community_translation/translation')->findBy(array('tTranslatable' => $translatable, 'tLocale' => $locale), array('tCreatedOn' => 'DESC'));
        foreach ($translations as $translation) {
            $texts = array();
            switch ($numPlurals) {
                case 6:
                    $texts[] = $translation->getText5();
                    /* @noinspection PhpMissingBreakStatementInspection */
                case 5:
                    $texts[] = $translation->getText4();
                    /* @noinspection PhpMissingBreakStatementInspection */
                case 4:
                    $texts[] = $translation->getText3();
                    /* @noinspection PhpMissingBreakStatementInspection */
                case 3:
                    $texts[] = $translation->getText2();
                    /* @noinspection PhpMissingBreakStatementInspection */
                case 2:
                    $texts[] = $translation->getText1();
                    /* @noinspection PhpMissingBreakStatementInspection */
                case 1:
                default:
                    $texts[] = $translation->getText0();
                    break;
            }
            $item = array(
                'id' => $translation->getID(),
                'created' => $translation->getCreatedOn(),
                'createdBy' => $translation->getCreatedBy(),
                'current' => $translation->isCurrent(),
                'currentSince' => $translation->isCurrentSince(),
                'reviewed' => $translation->isReviewed(),
                'texts' => array_reverse($texts),
            );
        }

        return $result;
    }

    /**
     * Get the comments associated to a translatable strings.
     *
     * @param Locale $locale
     * @param Translatable $translatable
     */
    public function getComments(Locale $locale, Translatable $translatable, Comment $parentComment = null)
    {
        $repo = $this->app->make('community_translation/translatable/comment');
        if ($parentComment === null) {
            $qb = $repo->createQueryBuilder('c');
            $qb
                ->where('c.tcTranslatable = :translatable')
                ->andWhere('c.tcParentComment is null')
                ->andWhere($qb->expr()->orX(
                    'c.tcLocale = :locale',
                    'c.tcLocale is null'
                ))
                ->orderBy('c.tcPostedOn', 'ASC')
                ->setParameter('translatable', $translatable)
                ->setParameter('locale', $locale)
                ;
            $comments = $qb->getQuery()->getResult();
        } else {
            $comments = $repo->findBy(
                array('tcParentComment' => $parentComment),
                array('tcPostedOn' => 'ASC')
            );
        }
        $result = array();
        foreach ($comments as $comment) {
            $result[] = array(
                'id' => $comment->getID(),
                'date' => $comment->getPostedOn(),
                'by' => $comment->getPostedBy(),
                'text' => $comment->getText(),
                'comments' => $this->getComments($locale, $translatable, $comment),
            );
        }

        return $result;
    }

    /**
     * Search for similar translations.
     *
     * @param Locale $locale
     * @param Translatable $translatable
     *
     * @return array
     */
    public function getSuggestions(Locale $locale, Translatable $translatable)
    {
        $result = array();
        $connection = $this->app->make('community_translation/em')->getConnection();
        $rs = $connection->executeQuery(
            '
                select
                    Translatables.tText,
                    Translations.tText0,
                    match(Translatables.tText) against (:search in natural language mode) as relevance
                from
                    Translations
                    inner join Translatables on Translations.tTranslatable = Translatables.tID and 1 = Translations.tCurrent and :locale = Translations.tLocale
                where
                    Translatables.tID <> :currentTranslatableID
                    and length(Translatables.tText) between :minLength and :maxLength
                having
{'fraction_non_alphanumeric': 0.11794315805777124, 'fraction_numerical': 0.002787888174707659, 'mean_word_length': 1.8282961016206745, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 124, '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': '2337977', 'n_tokens_mistral': 3496, 'n_tokens_neox': 3279, 'n_words': 732}