I want know if is possible (and how?) overwrite doctrine setters when we use i18n actAs...
I'm trying something like this:
class Category extends BaseCategory
{
/*
* Overwrite save method
*/
public function save(Doctrine_Connection $conn = null)
{
$conn = $conn ? $conn : $this->getTable()->getConnection();
$conn->beginTransaction();
try
{
$this->setSlug();
$ret = parent::save($conn);
$conn->commit();
return $ret;
}
catch (Exception $e)
{
$conn->rollBack();
throw $e;
}
}
public function setSlug()
{
$slug = $this->getName() . 'lala lala';
parent::_set('slug', $slug);
}
.....
But only save the $slug value in one lang (I have 2 languages).
Any Idea??
Thanks A Lot!
Thanks for replaying. I solved it like this:
$cultures =
sfConfig::get('app_cultures');
// seteamos slug
foreach($cultures as $culture)
{
parent::_set('slug', 'lala lala');
} ...
You can simply loop through the translations:
foreach($this->Translations as $lang => $t) {
$t->slug = $t->name.'lala';
}
Related
Hello I have a common function which looks like below,
public async Task<SPResponse> ExecuteAsync(string spName, DynamicParameters p)
{
SPResponse response = new SPResponse();
using (SqlConnection conn = new SqlConnection(_connStr))
{
conn.Open();
using (SqlTransaction transaction = conn.BeginTransaction(IsolationLevel.ReadCommitted))
{
try
{
p.Add("#SP_MESSAGE", dbType: DbType.String, direction: ParameterDirection.Output, size: 4000);
p.Add("#RETURNSTATUS", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);
await conn.ExecuteAsync(sql: spName, param: p, commandType: CommandType.StoredProcedure, transaction: transaction);
response.ReturnMessage = p.Get<string>("#SP_MESSAGE");
response.ReturnStatus = Convert.ToString(p.Get<int>("#RETURNSTATUS"));
if (response.ReturnStatus == "0")
{
response.Ref1 = Convert.ToString(p.Get<int>("#SP_ID"));
transaction.Commit();
}
else
{
transaction.Rollback();
}
}
catch (Exception ex)
{
Utils.Logger.Instance.LogException(ex);
transaction.Rollback();
}
conn.Close();
}
}
return response;
}
now on response.Ref1 = Convert.ToString(p.Get<int>("#SP_ID")); line in some of my procedure I am getting SP_ID as output parameter and in some I am not getting SP_ID as output parameter
but the problem is when I am not returning SP_ID as output parameter I am getting error of
The given key was not present in the dictionary.
I want to check the key before execution of p.get<int>()
how can I do this?
So I fixed this by myself and thanks to #MarcGravell.
I declared a parameter in my DapperClass where I am using common ExecuteAsync method.
private DynamicParameters _Param;
public DapperClass()
{
_Param = new DynamicParameters();
}
now before transaction.Commit() line I am assigning the value to my parameter _Param = p;
and I created a public method with return type of DynamicParameters like below
public DynamicParameters GetDynamicParameters()
{
return _Param;
}
and also added a code like below from where I am executing my common dapper class
SPResponse response = await _Dapper.ExecuteAsync("[dbo].[TemplateAdd]", _DynamicParameter);
if (response.ReturnStatus == "0")
{
DynamicParameters dp = _Dapper.GetDynamicParameters();
response.Ref1 = Convert.ToString(dp.Get<int>("#SP_ID"));
response.Ref2 = request.FileServerId;
}
In Zend Frameword 2.5 a review and saw some code, it works fine but my IDE shows error about it.
I don't know purpose of this code snippet.
Why to write: $this->table = clone $this->table;
Github Link: https://github.com/zendframework/zend-db/blob/master/src/TableGateway/AbstractTableGateway.php
Function: rows 529-544
Please explain to me about it.
public function __clone()
{
$this->resultSetPrototype = (isset($this->resultSetPrototype)) ? clone $this->resultSetPrototype : null;
$this->sql = clone $this->sql;
if (is_object($this->table)) {
$this->table = clone $this->table;
} elseif (
is_array($this->table)
&& count($this->table) == 1
&& is_object(reset($this->table))
) {
foreach ($this->table as $alias => &$tableObject) {
$tableObject = clone $tableObject;
}
}
}
I can't understand Zend purpose but i hope after run two below code snippet, from different two results, you can understand
<?php
class A {
public $foo = 1;
}
class B {
protected $value = 1;
protected $bar = null;//
public function __construct() {
$this->bar = new A();
}
public function setValue($foo = 3){
$this->value = $foo;
}
public function setFooBar($foo = 3){
$this->bar->foo = $foo;
}
public function __clone() {
$this->bar = clone($this->bar);
}
}
$a = new B();
$c = clone($a);
$c->setFooBar(3);
$c->setValue(6);
var_dump($a);
echo "\n";
var_dump($c);
?>
<?php
class A {
public $foo = 1;
}
class B {
protected $value = 1;
protected $bar = null;//
public function __construct() {
$this->bar = new A();
}
public function setValue($foo = 3){
$this->value = $foo;
}
public function setFooBar($foo = 3){
$this->bar->foo = $foo;
}
}
$a = new B();
$c = clone($a);
$c->setFooBar(3);
$c->setValue(6);
var_dump($a);
echo "\n";
var_dump($c);
?>
clone (or __clone) is a so called magic method. Check for reference on other magic methods the php documentation on magic methods here.
Check also the specific documentation for clone where they explain the working of this magic method:
An object copy is created by using the clone keyword (which calls the object's __clone() method if possible). An object's __clone() method cannot be called directly.
In other words it allows you to define custom cloning behavior for an object instance inside its class definition using a public __clone method. This method will be called "magically" when you do:
$clone = clone $instance;
I am struggling to validate (non-duplication) globally, across multiple files that do not explicitly reference each other.
Consider the standard initally-generated grammar
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
Model:
greetings+=Greeting*;
Greeting:
'Hello' name=ID '!';
It is simple to validate that no file contains greeting for the same name.
package org.xtext.example.mydsl.validation
import org.eclipse.xtext.validation.Check
import org.xtext.example.mydsl.myDsl.Greeting
import org.xtext.example.mydsl.myDsl.Model
import org.xtext.example.mydsl.myDsl.MyDslPackage
class MyDslValidator extends AbstractMyDslValidator {
public static val LOCALLY_DUPLICATE_NAME = 'LOCALLY_DUPLICATE_NAME'
#Check
def checkGreetingLocallyUnique(Greeting greeting) {
for(greeting_ : (greeting.eContainer as Model).greetings) {
if(greeting!==greeting_ && greeting.name==greeting_.name) {
warning('Greeting duplication',
MyDslPackage.Literals.GREETING__NAME,
LOCALLY_DUPLICATE_NAME)
}
}
}
}
I do not understand how to validate non-duplication against all the files known to the global-index.
The stub of the method is
#Check
def checkGreetingGloballyUnique(Greeting greeting) {
for(greeting_ : /*???*/ ) {
if(greeting!==greeting_ && greeting.name==greeting_.name) {
warning('Global Greeting duplication',
MyDslPackage.Literals.GREETING__NAME,
GLOBALLY_DUPLICATE_NAME)
}
}
}
How do I get access to the global index from within the validator?
the easiest way for a local duplicate validation is to enable it in the workflow and regenerate the language (this does not check locally though)
validator = {
composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
}
to search the index
#Inject
IContainer.Manager containermanager;
#Inject
ResourceDescriptionsProvider resourceDescriptionsProvider;
public .... getAllEntitiesFor( EObject eObject ) {
....
IResourceDescriptions resourceDescriptions = resourceDescriptionsProvider.getResourceDescriptions( eObject.eResource() );
IResourceDescription resourceDescription = resourceDescriptions.getResourceDescription( eObject.eResource().getURI() );
List<IContainer> visiblecontainers = containermanager.getVisibleContainers( resourceDescription, resourceDescriptions );
for (IContainer container : visiblecontainers) {
for (IEObjectDescription eobjectDescription : container.getExportedObjects()) {
EObject eObjectOrProxy = eobjectDescription.getEObjectOrProxy();
.....
}
}
....
}
After much hacking, I obtained the following.
public static val GLOBALLY_DUPLICATE_NAME = 'GLOBALLY_DUPLICATE_NAME'
#com.google.inject.Inject
IResourceDescriptions iResourceDescriptions
#Inject
Provider<XtextResourceSet> resourceSetProvider;
#Check
def checkGreetingGloballyUnique(Greeting greeting) {
for (resourceDescriptions : iResourceDescriptions.allResourceDescriptions) {
for (_greetingDescription : resourceDescriptions.getExportedObjectsByType(MyDslPackage.Literals.GREETING)) {
val _greeting = resourceSetProvider.get.getEObject(_greetingDescription.EObjectURI, true) as Greeting
// don't use equality, ALWAYS not equal!!
if (greeting.eResource.URI != _greeting.eResource.URI) {
// this means distinct files, all greetings in same file have same uri
if (greeting.name == _greeting.name) {
warning('Global greeting duplication', MyDslPackage.Literals.GREETING__NAME,
LOCALLY_DUPLICATE_NAME)
}
}
}
}
}
Rewrite, based on #Christian Dietrich's comments, I have the following solution.
#Inject
IContainer.Manager containerManager;
#com.google.inject.Inject
IResourceDescriptions resourceDescriptions
#Inject
Provider<XtextResourceSet> resourceSetProvider;
#Check
def checkGreetingGloballyUnique(Greeting greeting) {
var greeting_description = resourceDescriptions.getResourceDescription(greeting.eResource.URI)
var visibleContainers = containerManager.getVisibleContainers(greeting_description, resourceDescriptions)
for (visibleContainer : visibleContainers) {
for (_greetingDescription : visibleContainer.getExportedObjectsByType(MyDslPackage.Literals.GREETING)) {
val _greeting = resourceSetProvider.get.getEObject(_greetingDescription.EObjectURI, true) as Greeting
// don't use equality, ALWAYS greeting != _greeting !!
if (greeting.eResource.URI != _greeting.eResource.URI) {
// this means distinct files, all greetings in same file have same uri
if (greeting.name == _greeting.name) {
warning('Global greeting duplication', MyDslPackage.Literals.GREETING__NAME,
GLOBALLY_DUPLICATE_NAME)
}
}
}
}
}
I am new to the dependency injection pattern and I am having issues getting a new instance of a class from container.Resolve in tinyioc it just keeps returning the same instance rather than a new instance. Now for the code
public abstract class HObjectBase : Object
{
private string _name = String.Empty;
public string Name
{
get
{
return this._name;
}
set
{
if (this._name == string.Empty && value.Length > 0 && value != String.Empty)
this._name = value;
else if (value.Length < 1 && value == String.Empty)
throw new FieldAccessException("Objects names cannot be blank");
else
throw new FieldAccessException("Once the internal name of an object has been set it cannot be changed");
}
}
private Guid _id = new Guid();
public Guid Id
{
get
{
return this._id;
}
set
{
if (this._id == new Guid())
this._id = value;
else
throw new FieldAccessException("Once the internal id of an object has been set it cannot be changed");
}
}
private HObjectBase _parent = null;
public HObjectBase Parent
{
get
{
return this._parent;
}
set
{
if (this._parent == null)
this._parent = value;
else
throw new FieldAccessException("Once the parent of an object has been set it cannot be changed");
}
}
}
public abstract class HZoneBase : HObjectBase
{
public new HObjectBase Parent
{
get
{
return base.Parent;
}
set
{
if (value == null || value.GetType() == typeof(HZoneBase))
{
base.Parent = value;
}
else
{
throw new FieldAccessException("Zones may only have other zones as parents");
}
}
}
private IHMetaDataStore _store;
public HZoneBase(IHMetaDataStore store)
{
this._store = store;
}
public void Save()
{
this._store.SaveZone(this);
}
}
And the derived class is a dummy at the moment but here it is
public class HZone : HZoneBase
{
public HZone(IHMetaDataStore store)
: base(store)
{
}
}
Now since this is meant to be an external library I have a faced class for accessing
everything
public class Hadrian
{
private TinyIoCContainer _container;
public Hadrian(IHMetaDataStore store)
{
this._container = new TinyIoCContainer();
this._container.Register(store);
this._container.AutoRegister();
}
public HZoneBase NewZone()
{
return _container.Resolve<HZoneBase>();
}
public HZoneBase GetZone(Guid id)
{
var metadataStore = this._container.Resolve<IHMetaDataStore>();
return metadataStore.GetZone(id);
}
public List<HZoneBase> ListRootZones()
{
var metadataStore = this._container.Resolve<IHMetaDataStore>();
return metadataStore.ListRootZones();
}
}
However the test is failing because the GetNewZone() method on the Hadrian class keeps returning the same instance.
Test Code
[Fact]
public void ListZones()
{
Hadrian instance = new Hadrian(new MemoryMetaDataStore());
Guid[] guids = { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() };
int cnt = 0;
foreach (Guid guid in guids)
{
HZone zone = (HZone)instance.NewZone();
zone.Id = guids[cnt];
zone.Name = "Testing" + cnt.ToString();
zone.Parent = null;
zone.Save();
cnt++;
}
cnt = 0;
foreach (HZone zone in instance.ListRootZones())
{
Assert.Equal(zone.Id, guids[cnt]);
Assert.Equal(zone.Name, "Testing" + cnt.ToString());
Assert.Equal(zone.Parent, null);
}
}
I know its probably something simple I'm missing with the pattern but I'm not sure, any help would be appreciated.
First, please always simplify the code to what is absolutely necessary to demonstrate the problem, but provide enough that it will actually run; I had to guess what MemoryMetaDataStore does and implement it myself to run the code.
Also, please say where and how stuff fails, to point others straight to the issue. I spent a few minues figuring out that the exception I was getting was your problem and you weren't even getting to the assertions.
That said, container.Resolve<HZoneBase>() will always return the same instance because that's how autoregistration in TinyIoC works - once an abstraction has been resolved, the same instance is always returned for subsequent calls.
To change this, add the following line to the Hadrian constructor:
this._container.Register<HZoneBase, HZone>().AsMultiInstance();
This will tell the container to create a new instance for each resolution request for HZoneBase.
Also, Bassetassen's answer about the Assert part is correct.
In general, if you want to learn DI, you should read Mark Seemann's excellent book "Dependency Injection in .NET" - not quite an easy read as the whole topic is inherently complex, but it's more than worth it and will let you get into it a few years faster than by learning it on your own.
In your assert stage you are not incrementing cnt. You are also using the actual value as the expected one in the assert. This will be confusing, becuase it says something is excpected when it actually is the actual value that is returned.
The assert part should be:
cnt = 0;
foreach (HZone zone in instance.ListRootZones())
{
Assert.Equal(guids[cnt], zone.Id);
Assert.Equal("Testing" + cnt.ToString(), zone.Name);
Assert.Equal(null, zone.Parent);
cnt++;
}
I have a few forms configured in symfony. One things I need is to have an asterisk (*) or other indicator next to fields that are required. The fields are all set to required int he form framework, and return a "this field is required" error when the form is submitted, but I want an indicator before the form is submitted.
If there any way to do this without overriding the labels for each field manually?
Here's an automatic solution found in Kris Wallsmith's blog:
lib/formatter/RequiredLabelsFormatterTable.class.php, this will add a 'required' class to the labels of required fields
<?php
class RequiredLabelsFormatterTable extends sfWidgetFormSchemaFormatterTable
{
protected
$requiredLabelClass = 'required';
public function generateLabel($name, $attributes = array())
{
// loop up to find the "required_fields" option
$widget = $this->widgetSchema;
do {
$requiredFields = (array) $widget->getOption('required_fields');
} while ($widget = $widget->getParent());
// add a class (non-destructively) if the field is required
if (in_array($this->widgetSchema->generateName($name), $requiredFields)) {
$attributes['class'] = isset($attributes['class']) ?
$attributes['class'].' '.$this->requiredLabelClass :
$this->requiredLabelClass;
}
return parent::generateLabel($name, $attributes);
}
}
lib/form/BaseForm.class.php, this is the common base class for all the forms in your project:
protected function getRequiredFields(sfValidatorSchema $validatorSchema = null, $format = null)
{
if (is_null($validatorSchema)) {
$validatorSchema = $this->validatorSchema;
}
if (is_null($format)) {
$format = $this->widgetSchema->getNameFormat();
}
$fields = array();
foreach ($validatorSchema->getFields() as $name => $validator) {
$field = sprintf($format, $name);
if ($validator instanceof sfValidatorSchema) {
// recur
$fields = array_merge(
$fields,
$this->getRequiredFields($validator, $field.'[%s]')
);
} else if ($validator->getOption('required')) {
// this field is required
$fields[] = $field;
}
}
return $fields;
}
add the following few lines to BaseForm as well, in the __construct() method:
$this->widgetSchema->addOption("required_fields", $this->getRequiredFields());
$this->widgetSchema->addFormFormatter('table',
new RequiredLabelsFormatterTable($this->widgetSchema)
);
After all this, all your labels will have the required class, use whatever css you need to mark it to the user.
What about the simpler solution from the original cookbook - just a few lines in twig:
http://symfony.com/doc/2.1/cookbook/form/form_customization.html#adding-a-required-asterisk-to-field-labels
you can set the field's class as part of the constructor of the sfWidget
i.e.
$this->widgetSchema['form_field'] = new sfWidgetFormInput(array(), array('class' => 'required_field'));
Note: this is assuming you're not on the ancient sfForms (ala 1.0)
UPDATE
here is some CSS code from techchorus.net to show the required asterisk
.required
{
background-image:url(/path/to/your/images/dir/required-field.png);
background-position:top right;
background-repeat:no-repeat;
padding-right:10px;
}
I did it using Javascript:
$('form').find('select, input, textarea').each(function(){
if($(this).attr('required') == 'required'){
$label = $('label[for='+ $(this).attr('id') +']');
if($label.find('.required-field').length == 0){
$label.append('<span class="required-field">*</span>');
}
}
});