Как иметь менеджер моделей в Symfony2? - PullRequest
4 голосов
/ 29 марта 2012

Извините, если на этот вопрос уже был дан ответ, я не смог найти ни одного.

Я строю эту модель в Symfony2:

class LogEntry {
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var \DateTime $log_timestamp
     *
     * @ORM\Column(name="log_timestamp", type="datetime")
     */
    private $log_timestamp;

    /**
     * @var TranslationMapping $source
     *
     * @ORM\ManyToOne(targetEntity="TranslationMapping", cascade={"persist"})
     * @ORM\JoinColumn(name="source", referencedColumnName="id")
     */
    private $source;

    /**
     * @var TranslationMapping $target
     *
     * @ORM\ManyToOne(targetEntity="TranslationMapping", cascade={"persist"})
     * @ORM\JoinColumn(name="target", referencedColumnName="id")
     */
    private $target;
...
}

С TranslationMapping так:

/**
 * LogAnalyzer\Bundle\CombatLogBundle\Entity\TranslationMapping
 *
 * @ORM\Table(name="TranslationMapping", uniqueConstraints={@ORM\UniqueConstraint(name="idValue_idx", columns={"stringId", "stringValue"})})
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks()
 */
class TranslationMapping
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string $stringId
     *
     * @ORM\Column(name="stringId", type="string", length=255)
     */
    private $stringId;

    /**
     * @var string $stringValue
     *
     * @ORM\Column(name="stringValue", type="string", length=255)
     */
    private $stringValue;


    /**
     * @ORM\PrePersist
     */
    public function beforePersist()
    {
        if ($this->stringId == null) {
            $this->stringId = "laGen_".time();
        }
    }

LogEntry построен на основе строки, проанализированной через регулярное выражение. TranslationMapping представляет сохраненную в ключе / значении строку перевода.

В настоящее время я делаю следующее:

  1. Получение строки для построения LogEntry
  2. Построение LogEntry из строки в LogEntryRepository

    $logEntry = new LogEntry();
    $source = new TranslationMapping();
    if ($logEntry->getSourceIsPlayer()) {
        $source->setValueKey(str_replace("@", "", $matches["source"][0]));
    } else {
        $source->setValueKey($matches["source"][0], $matches["source_id"][0]);
        if (isset($matches["source_companion_name"][0])) { // It's a companion !
            $companion = new TranslationMapping();
            $companion->setValueKey($matches["source_companion_name"][0], $matches["source_companion_id"][0]);
            $logEntry->setSourceCompanion($companion);
            $source->setValueKey(str_replace("@", "", $matches["source"][0])); // And the source is the player's character name
        }
    }
    $logEntry->setSource($source);
    $logEntry->setTargetIsPlayer(strpos($matches["target"][0], "@") !== false);
    $target = new TranslationMapping();
    if ($logEntry->getTargetIsPlayer()) {
        $target->setValueKey(str_replace("@", "", $matches["target"][0]));
    } else {
        $target->setValueKey($matches["target"][0], $matches["target_id"][0]);
        if (isset($matches["target_companion_name"][0])) { // It's a companion !
            $companion = new TranslationMapping();
            $companion->setValueKey($matches["target_companion_name"][0], $matches["target_companion_id"][0]);
            $logEntry->setTargetCompanion($companion);
            $target->setValueKey(str_replace("@", "", $matches["target"][0])); // And the target is the player's character name
        }
    }
    $logEntry->setTarget($target);
    
  3. Отображение LogEntry

Моя проблема в том, что я хочу создать объект отображения перевода, если пара ключ / значение еще не существует. Тем не менее, я не понимаю, как я могу это сделать, так как:

  • Я не могу получить доступ к TranslationMappingRepository из другого хранилища
  • Я не могу получить доступ к Сервису из репозитория
  • Я не могу использовать INSERT ... ON DUPLICATE KEY UPDATE запросы через Doctrine2

По сути, я пытаюсь получить Менеджер для моих сущностей TranslationMapping, который будет управлять операциями БД (извлекать и вставлять, если необходимо) и выставлять сущности через все приложения Symfony, и в основном в Репозитории.

Я пробовал несколько решений и исчерпал варианты, кто-нибудь знает, как мне этого добиться?

Спасибо.

1 Ответ

5 голосов
/ 29 марта 2012

По сути, вы хотите создать сервис S2 и внедрить в него вашего менеджера сущностей. В руководстве много примеров, хотя я мог бы опубликовать один, если он вам действительно нужен.

Репозитории хороши при работе с одним типом сущности, но, как вы выяснили, не так много при работе с несколькими типами. Я редко их использую. Просто оберните функциональность в сервис.

INSERT ... ON DUPLICATE KEY UPDATE, к сожалению, не является стандартным sql и поэтому не поддерживается Doctrine, хотя вы можете добавить его в качестве пользовательской функции. Но лучше всего просто проверить, существует ли ключ, а затем настроить его соответствующим образом. Обязательно перехватывайте любые исключения на всякий случай.

Я не особо разбирался в вашем коде, но в S2 есть куча переводчиков. Возможно, что и это может помочь.

UPDATE:

Информацию о создании сервисов можно найти здесь: http://symfony.com/doc/current/book/service_container.html

В вашем файле services.xml может быть что-то вроде:

<service 
    id="zayso.core.project.manager"        
    class="Zayso\ZaysoBundle\Component\Manager\ProjectManager" public="true">
        <argument type="service" id="doctrine.orm.entity_manager" />
</service>

Ваш менеджер будет иметь __construct вроде:

class ProjectManager
{
    protected $em = null;

    public function getEntityManager() { return $this->em; }

    public function __construct($em) { $this->em = $em; }

И тогда в вашем контроллере вы будете делать что-то вроде:

$manager = $this->get(zayso.core.project.manager);
$manager->newLogEntry($params);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...