在我们最近更新到MySQL 5.6.27(来自Ubuntu repo)之后,此选项现在可用.所以这似乎是以前版本的MySQL的一个问题.
随着对MySQL(5.6.20)的新升级,除非我将sql-mode设置为NO_ENGINE_SUBSTITUTION,否则更新和插入将失败.
感谢文档,我可以从mysql终端运行以下内容并解决问题(暂时):
SET GLOBAL sql_mode = 'NO_ENGINE_SUBSTITUTION';
SET SESSION sql_mode = 'NO_ENGINE_SUBSTITUTION';`
Run Code Online (Sandbox Code Playgroud)
但是下次MySQL重启时,这些设置会丢失.
所以我试图通过编辑/etc/mysql/my.cnf(在我运行Ubuntu 12.04.5 LTS的标准服务器上)来创建永久物,然后添加文档中应该添加的配置设置:
[mysqld]
sql-mode="NO_ENGINE_SUBSTITUTION"
Run Code Online (Sandbox Code Playgroud)
仅出于测试目的,我还尝试了以下格式(重启MySQL时不会导致错误,但它们不会影响设置).
# dash no quotes
sql-mode=NO_ENGINE_SUBSTITUTION
# underscore no quotes
sql_mode=NO_ENGINE_SUBSTITUTION
# underscore and quotes
sql_mode="NO_ENGINE_SUBSTITUTION"
Run Code Online (Sandbox Code Playgroud)
什么都行不通.重启后,此设置丢失,我必须再次从mysql终端手动运行命令,以便再次保存.
我通过命令行运行它来获取正在引用的配置文件列表:
mysqld --help --verbose
Run Code Online (Sandbox Code Playgroud)
我看到一行内容如下:
Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf
Run Code Online (Sandbox Code Playgroud)
这是它"查找"文件的默认位置,它并不意味着它实际上在那里找到了一个文件,例如我的服务器没有/etc/my.cnf,/usr/etc/my.cnf或者~/.my.cnf.
所以看起来我的/etc/mysql/my.cnf中的配置是mysql引用的唯一文件,因此不会覆盖此设置.
从逻辑上讲,似乎语法不正确或因某些其他原因而被忽略.还有其他想法吗?
我有一个表格,允许我保存记录或复制它.表单将记录保存为$view实体,该实体恰好具有多个关联实体,例如$viewVersion由具有嵌套实体的formType中的表单构建器管理(这可能是无关紧要的).
如果我进行更改并将表单提交为"复制",则代码将$view使用我的实体上的函数克隆对象,该函数将取消设置$view->id和其他关联.这迫使Doctrine在将记录保存到数据库时创建新记录.这非常有效.欢呼!
但是,对记录所做的更改也会持久保存到克隆的原始实体(并因此保存到数据库中).因此它将这些更改保存到两个数据库记录中.我碰巧喜欢这个功能,但我需要理解为什么它正在这样做,所以它不会破坏.以下是摘要中相关的代码:
// File: CmsBundle/Controller/AdminEditController.php
// Get the Entity Manager
$em = $this->getDoctrine()->getManager();
// Get the View based on the requested ID
// Is there some magic that happens here to make the entity manager track this $view entity?
$view = $em->getRepository("GutensiteCmsBundle:View\View")->find($request->query->get('id'));
// Various bits of code to do whatever I want before a save
// ...
if ($request->isMethod( 'POST' )) {
$form->handleRequest($request);
if( $form->isValid() ) {
// Duplicate the view …Run Code Online (Sandbox Code Playgroud) 我可以使用Doctrine实体管理器(或其他一些Symfony函数)来检查实体是否已更新?
我正在构建一个能够保存每个页面"版本"的CMS.所以我有一个Doctrine注释实体$view(基本上就是"页面"),这个实体有嵌套的关联实体$view->version(包含可以在不同版本中更新的大部分信息).这个实体是用标准的Symfony形式编辑的在提交表单时,它执行a $em->persist($view),实体管理器检测是否有任何字段已更改.如果有更改,则更改将保持不变.如果没有更改,实体管理器将忽略持久性和保存自己的数据库调用以进行更新.很棒.
但是在保存实体之前,我的版本控制系统会检查自当前版本上次保存以来是否超过30分钟,或者提交表单的用户与保存当前版本的用户不同,如果是,则克隆$viewVersion.所以主要记录$view保持相同的ID,但它的工作原理是更新版本.这非常有效.
但是......如果自上次保存以来已经有一段时间了,有人只是在不改变任何内容的情况下查看记录,并且点击保存,我不希望版本系统自动克隆新版本.我想检查并确认实体已实际更改.实体管理器在持久化实体之前执行此操作.但我不能依赖它,因为在我打电话之前$em->persist($view)我必须克隆$view->version.但在克隆之前,我$view->version需要检查实体中的任何字段或嵌套实体是否已更新.
该解决方案是计算变更集:
$form = $this->createForm(new ViewType(), $view);
if ($request->isMethod( 'POST' )) {
$form->handleRequest($request);
if( $form->isValid() ) {
$changesFound = array();
$uow = $em->getUnitOfWork();
$uow->computeChangeSets();
// The Version (hard coded because it's dynamically associated)
$changeSet = $uow->getEntityChangeSet($view->getVersion());
if(!empty($changeSet)) {
$changesFound = array_merge($changesFound, $changeSet);
}
// Cycle through Each Association
$metadata = $em->getClassMetadata("GutensiteCmsBundle:View\ViewVersion");
$associations = $metadata->getAssociationMappings(); …Run Code Online (Sandbox Code Playgroud) 根据Symfony 2.4文档,任何不需要但没有任何值(选择字段的默认值或文本字段的空值)提交的表单字段将保存到具有NULL值的实体.因此,如果您的实体字段被定义为NOT NULL(例如,不是nullable = true),当您持久保存实体时,您将收到一个令人讨厌的错误:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'shell' cannot be null
Run Code Online (Sandbox Code Playgroud)
所以文档说如果你不希望它使用NULL作为默认值,你可以empty_data在文本或选择字段上指定属性.但是,这对我不起作用.
实体字段(不可为空):
/**
* @ORM\Column(type="string")
*/
protected $shell = '';
Run Code Online (Sandbox Code Playgroud)
表单生成器(不是必需的):
->add('shell', 'choice', array(
'label' => 'Shell',
'choices' => array('shell' => 'Fancy Pants'),
'required' => false,
'empty_data' => ''
))
Run Code Online (Sandbox Code Playgroud)
我误解了这个empty_data属性吗?我在别处错过了一些重要的设置吗?这样做的推荐方法是什么?
这张Github门票解释说这是2012年的问题,尚未修复.
这意味着每个使用表单构建器的人都被迫在可空字段中创建任何不需要的字段?对于框架来说,这似乎很自然......当默认的''或0不具有唯一含义而我们不需要NULL时,有很多原因我们不想使用NULL.对于许多查询,必须检查是否存在field = 0 OR field = NULL,这很痛苦.
是否有其他人使用的更好的解决方案?
Recaptcha在页面加载时突然开始窃取焦点,导致页面向下滚动到表单(非常烦人).这似乎是一个新的错误?
参见示例:http://www.gullixson.com/Contact-Us
显然,加载reCaptcha http://www.google.com/recaptcha/api/challenge?k=UNIQUEAPIKEY&lang=en的主要Google图书馆 需要http://www.google.com/recaptcha/api/js/recaptcha_canary .js文件
在那里,init()函数似乎触发reload()函数,这导致Recaptcha.focus_response_field()函数加载.
似乎我们无能为力......直到他们修复它?
有谁知道如何向Google报告此错误?或者解决这个问题的方法?
如果我有一个关联的实体是一个集合,你在获取时有什么选择?
例如,假设我有一个$view具有此定义的实体:
/**
* @ORM\OneToMany(targetEntity="\Gutensite\CmsBundle\Entity\View\ViewVersion", mappedBy="entity")
* @ORM\OrderBy({"timeMod" = "DESC"})
*/
protected $versions;
public function getVersions() {
return $this->versions;
}
Run Code Online (Sandbox Code Playgroud)
我希望得到与实体相关的所有版本,如下所示:
$view->getVersions();
Run Code Online (Sandbox Code Playgroud)
这将返回一个集合.大.但是有可能采用该集合并按标准过滤它,例如比某个日期更新吗?或者按一些(其他)标准订购?
或者此时您只是希望对存储库进行查询:
$versions = $em->getRepository("GutensiteCmsBundle:View\ViewVersion")->findBy(array(
array(
'viewId', $view->getId(),
'timeMod', time()-3600
)
// order by
array('timeMod', 'DESC')
));
Run Code Online (Sandbox Code Playgroud) 我已经为Doctrine onFlush事件监听器创建了一个服务.在这个监听器中,我想引用我在另一个服务中的常用函数来检查实体的快捷方式路径.那其他服务使用实体管理器要做到这一点,所以该服务定义其他服务注入学说实体管理器的构造函数的参数.但是,如果我在我的主onFlush事件监听器中包含其他服务,我会得到一个关于循环引用的令人讨厌的错误.
我可以让这个entity_helper服务在set函数中接受Entity Manager setEntityManager($entityManager).但这意味着每当我entity_helper在其他地方使用此服务时,我必须始终传入EntityManager.也许那没关系,但这是唯一的解决方案吗?开始时我的逻辑/理解是否有问题?(我是Symfony的新手,所以我经常出错).
图表A:令人讨厌的错误
Fatal error: Uncaught exception 'Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException' with message 'Circular reference detected for service "doctrine.dbal.cms_connection", path: "doctrine.dbal.cms_connection".' in /var/www/core/cms/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php:456 Stack trace: #0 /var/www/core/cms/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php(604): Symfony\Component\DependencyInjection\Dumper\PhpDumper->addServiceInlinedDefinitionsSetup('doctrine.dbal.c...', Object(Symfony\Component\DependencyInjection\Definition)) #1 /var/www/core/cms/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php(630): Symfony\Component\DependencyInjection\Dumper\PhpDumper->addService('doctrine.dbal.c...', Object(Symfony\Component\DependencyInjection\Definition)) #2 /var/www/core/cms/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php(117): Symfony\Componen in /var/www/core/cms/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php on line 456
Run Code Online (Sandbox Code Playgroud)
Services.yml
# This is the helper class for all entities
gutensite_cms.entity_helper:
class: Gutensite\CmsBundle\Service\EntityHelper
# This causes the Circular Reference Error when this service is included in …Run Code Online (Sandbox Code Playgroud) 如何在非标准目录中查找symfony以查找要为捆绑视图加载的"最佳"(自定义)Twig模板?
Symfony文档默认情况下会在两个位置查看覆盖Twig模板
呈现AcmeBlogBundle:Blog:index.html.twig时,Symfony实际上在模板的两个不同位置查找:
app/Resources/AcmeBlogBundle/views/Blog/index.html.twig src/Acme/BlogBundle/Resources/views/Blog/index.html.twig
但这是讨论如何覆盖供应商包.在我的情况下,我在/ src /中有本机包,我想在每个设计模板或客户端特定的基础上覆盖.它需要查看:
Client: /var/www/vhosts/{ID}/src
Template: /var/www/core/cms/src/Gutensite/TemplateBundle/Templates/Admin/src
Run Code Online (Sandbox Code Playgroud)
Twig Loader有一个方便的方法来添加路径:
$templatePath = '/var/www/core/cms/src/Gutensite/TemplateBundle/Templates/Admin/Resources/views';
$this->container->get('twig.loader')->prependPath($templatePath, 'template');
Run Code Online (Sandbox Code Playgroud)
这允许我注册模板资源的替代路径,以便我可以像这样渲染模板shell:
{%extends'@ template/shell/shell.html.twig'%}
但是当我想要覆盖一个包模板时,例如
Original: /var/www/core/cms/src/Gutensite/MenuBundle/Resources/views/Menu.html.twig
Custom: /var/www/core/cms/src/Gutensite/TemplateBundle/Templates/Admin/src/Gutensite/MenuBundle/Resources/views/Menu.html.twig
Run Code Online (Sandbox Code Playgroud)
如何注册通用/ src /文件,以便Symfony在那里查找对供应商包路径的所有引用,例如,尝试呈现@GutensiteMenu/Menu.html.twig将首先在自定义目录中查找1)客户端,2)模板,3)默认包目录那个名字.
因为我的TemplateBundle/Templates/Admin/Resources /位于非标准位置,所以assetic不会将它们转储到公共目录(或创建符号链接)...所以我不确定如何动态地使资产找到这些文件.
我也不确定如何加载这些其他位置的资产,例如这不起作用:
{% stylesheets '@GutensiteTemplateBundle/Templates/Admin/Resources/public/css/site.css' %}
<link rel="stylesheet" href="{{ asset_url }}">
{% endstylesheets %}
Run Code Online (Sandbox Code Playgroud)
大概是因为它没有倾倒.
我建立一个托管的CMS是包含与控制器和模板,如各种束核心供应商/Gutensite/CmsBundle,Gutensite/ArticleBundle.
基于为站点选择的"设计模板",在TemplateBundle中引用设计模板,例如/TemplateBundle/Templates/Admin(称为"Admin"的模板).TemplateBundle需要能够覆盖核心控制器或视图.
我已经注册了Gutensite/TemplateBundle/Templates/Admin/src /文件夹作为Composer app/autoload.php的替代命名空间,因此只要控制器具有相同的Gutensite命名空间(并且效果很好),就可以覆盖控制器:
// in my primary controller:
$loader = $GLOBALS['loader'];
$loader->add('Gutensite', '/var/www/core/cms/src/Gutensite/TemplateBundle/Templates/Admin/src', …Run Code Online (Sandbox Code Playgroud) 我有很多配置设置,我希望能够在整个应用程序中访问.例如,我有一个包含一些自定义查询的实体存储库.我想有一个全局参数,将默认的"限制"设置为10条记录,除非我专门更改它.
class ViewVersionRepository extends EntityRepository {
/**
* Get all the versions for the specified view id, ordered by modification time.
* @param integer $id
* @param integer $limit
* @param integer $offset default 0
* @return array
*/
public function findByViewIdLimit($id, $limit = NULL, $offset = 0) {
// this won't work because we don't have access to the container... ;(
$limit = ($limit != NULL) ? $limit : $this->container->getParameter('cms.limit');
return $this->createQueryBuilder('v')
->where('v.viewId = :id')
->orderBy('v.timeMod', 'DESC')
->setParameter('id', $id) …Run Code Online (Sandbox Code Playgroud) 我需要修改表单(标签和类)中的某些字段,具体取决于实体是否是最新发布的版本.所以我需要能够将实体管理器注入到我的formType中,以便在事件监听器中我可以将当前版本与实体的已发布版本进行比较.但我甚entityManager至无法进入__construct()开始.也许有更好的方法来实现我的大目标(例如修改树枝模板中的表单),但我需要了解如何执行此基本依赖注入.
我认为,如果我在我的服务中声明它(如文档描述的基本服务容器和特定的构造函数注入方法),它将作为我的构造中的参数.但是当我这样做时,我得到错误:
Catchable fatal error: Argument 1 passed to Gutensite\CmsBundle\Form\Type\ViewType::__construct() must be an instance of Doctrine\ORM\EntityManager, none given, called in /var/www/core/cms/src/Gutensite/ArticleBundle/Controller/AdminEditController.php on line 222 and defined in /var/www/core/cms/src/Gutensite/CmsBundle/Form/Type/ViewType.php on line 15
以下是我的代码中的代码段:
Gutensite/CmsBundle /资源/配置/ service.yml
gutensite_cms.form.type.view:
class: Gutensite\CmsBundle\Form\Type\ViewType
arguments: [ "@doctrine.orm.entity_manager" ]
Run Code Online (Sandbox Code Playgroud)
Gutensite/CmsBundle /表/类型/ ViewType.php
namespace Gutensite\CmsBundle\Form\Type;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Form\AbstractType;
class ViewType extends AbstractType
{
private $em;
public function __construct(EntityManager $entityManager) {
$this->em = $entityManager;
}
}
Run Code Online (Sandbox Code Playgroud)
Gutensite/ArticleBundle /控制器/ AdminEditController.php
// Get the …Run Code Online (Sandbox Code Playgroud) 强制学说从查询JOIN加载嵌套关联实体的最佳方法是什么?
我有多个实体(view,contentType,version,settings),有三个关联级别:
view (primary entity)
contentType (ManyToOne joined on view.contentTypeId = contentType.id)
version (OneToMany joined on version.viewId = view.id)
settings (OneToOne joined on settings.versionId = version.id)
Run Code Online (Sandbox Code Playgroud)
我有一个列表查询所有版本(不是视图)以获取最近修改的版本.但我从view和contentType和访问属性settings.我contentType通过访问view(所以它是两层深).当我在循环中引用这些属性时,我不希望Doctrine Lazy在每个循环中使用N个查询加载每个值.
所以我在查询中加入实体,并选择所有字段.
$versionRepo = $em->getRepository('GutensiteCmsBundle:View\ViewVersion');
$queryBuilder = $versionRepo->createQueryBuilder('e')
->join('e.view', 'view')
->addSelect('view')
->join('view.contentType', 'contentType')
->addSelect('contentType')
->join('e.settings', 'settings')
->where('e.siteId = :siteid')->setParameter('siteId', 1)
->setMaxLimit(25);
Run Code Online (Sandbox Code Playgroud)
第一级链接ARE正确获取,例如version.view.但是,doctrine处理version.settings类似于延迟的负载,并且我将有25个额外的查询来加载每个单独的值.
所以即使我加入settings它仍然是懒惰加载.
我有一个被称为实体的实体foo,它与一个被称为bar可被访问的实体$foo->getBar()(一个ArrayCollection)有一个OneToMany关联.通常,调用$foo->getBar()会触发关联bar实体的延迟加载(如果它们最初未加入).
如何bar在不触发延迟加载的情况下检查是否已加载?我不需要关联的实体,如果它们最初没有加载,我不希望它们加载,我只想知道它们是否被加载.
在fooRepository我有一个被调用的方法getFooWithBar(),它有一个连接,它加载所有的barsArrayCollection并返回foo所有相关的bar实体.但是如果我只是简单地调用一个简单的方法getFooById(),那么bar实体就没有加载连接,所以它们不包含在中$foo.
所以在另一个控制器中我有$ foo,我想检查是否getBar()已加载关联实体,但我不想触发延迟加载.如果它没有关联的实体,我不想要它们.我只需要知道他们是否已被装载.
注意:我也不想在所有实例的实体关联上关闭延迟加载.
我把这个神奇的getter方法放在我的实体中:
public function __get($property) {
return isset($this->$property) ? $this->$property : null;
}
Run Code Online (Sandbox Code Playgroud)
从理论上讲,我可以检查属性是否已设置(或者它是否仍然是默认的私有声明).当我的实体是拥有方时,这就有效.但如果它是反面,那么$ this-> property永远不会被设置.Doctrine做了一些奇特的东西,所以当你这样做时,getProperty()它会在其他地方查看数据.我想出了这个,因为当它是拥有方(它返回关联实体的代理)时,此函数有效,但是null当关联实体由另一个实体拥有时它返回.
symfony ×10
doctrine-orm ×7
php ×7
doctrine ×2
forms ×1
javascript ×1
mysql ×1
recaptcha ×1
twig ×1