language form-add new field

How to configure and adapt Aimeos based shops as developer
Forum rules
Always add your Aimeos and PHP version as well as your environment (Linux/Mac/Win)
Spam and unrelated posts will be removed immediately!
khizar
Posts: 99
Joined: 19 Jan 2021, 09:51

Re: language form-add new field

Post by khizar » 26 Jan 2021, 09:25

aimeos wrote: 26 Jan 2021, 09:00 You've done all necessary steps and I can't see anything missing. There's just an error somewhere. Did you check what's happening in the fromArray() methods for which I've added the links?
i put the "test entry" manually in database field and added a die and dump at the end of my toArray method inside
Standard.php(Locale/Item/Language)

Code: Select all

public function toArray( bool $private = false ) : array
	{
		
		$list = parent::toArray( $private );
		
		$list['locale.language.code'] = $this->getCode();
		$list['locale.language.label'] = $this->getLabel();
		$list['locale.language.status'] = $this->getStatus();
		dd($list);
		return $list;
	}
so it gave me
following

Code: Select all

	array:9 [▼
  "locale.language.id" => "zu"
  "locale.language.siteid" => ""
  "locale.language.ctime" => "2020-12-21 06:48:54"
  "locale.language.mtime" => "2021-01-25 06:52:53"
  "locale.language.editor" => "info@zsoft.com.pk"
  "test" => "test entry"
  "locale.language.code" => "zu"
  "locale.language.label" => "Zulusdfdfsdsadsd"
  "locale.language.status" => 0
]
so i replaced

Code: Select all

value="<?= $enc->attr( $this->get( 'itemData/locale.language.test' ) ); ?>"
with

Code: Select all

value="<?= $enc->attr( $this->get( 'itemData/test' ) ); ?>"
in template file through which i am able to display value in my new field but now when i hit save button it gives me error
because of "test" which should be locale.language.test
i also added dd in my from array at the end

Code: Select all

$item = parent::fromArray( $list, $private );

		foreach( $list as $key => $value )
		{
			switch( $key )
			{
				case 'locale.language.code': $item = $item->setCode( $value ); break;
				case 'locale.language.label': $item = $item->setLabel( $value ); break;
				case 'locale.language.status': $item = $item->setStatus( (int) $value ); break;
				default: continue 2;
			}

			unset( $list[$key] );
		}
		dd($item);
		return $item;
which gives me

Code: Select all

Aimeos\MShop\Locale\Item\Language\Standard {#1556 ▼
  -prefix: "locale.language."
  -available: true
  -modified: true
  #bdata: array:8 [▼
    "test" => "test entry"
    "locale.language.id" => "zu"
    "locale.language.label" => "Zulusdfdfsdsadsddfdf"
    "locale.language.status" => "0"
    "locale.language.mtime" => "2021-01-25 06:52:53"
    "locale.language.editor" => "info@zsoft.com.pk"
    "locale.language.ctime" => "2020-12-21 06:48:54"
    "locale.language.code" => "zu"
  ]
}

User avatar
aimeos
Administrator
Posts: 7866
Joined: 01 Jan 1970, 00:00

Re: language form-add new field

Post by aimeos » 26 Jan 2021, 09:38

Rename "locale.language.test" to "test" everywhere, then it will work
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

khizar
Posts: 99
Joined: 19 Jan 2021, 09:51

Re: language form-add new field

Post by khizar » 26 Jan 2021, 10:27

aimeos wrote: 26 Jan 2021, 09:38 Rename "locale.language.test" to "test" everywhere, then it will work
thankyou for your response i have done that step and value was stored.thankyou so much again.
actually i have another task and i have given a task to
add a field city in site form for which i have done same steps which i have done for language form .
1) i overwrite my template file item-sites(this file is in ai-sites extension) and directory i have used is
ext\moudhah\admin\jqadm\templates\locale\site and after that i have added a line "ai-sites" in the depends array of
manifest file(in the root off my extension)

Code: Select all

<?php

return array(
	'name' => 'moudhah',
	'depends' => array(
		'aimeos-core',
		'ai-admin-jqadm',
		'ai-admin-jsonadm',
		'ai-client-html',
		'ai-client-jsonapi',
		'ai-controller-jobs',
		'ai-controller-frontend',
		'ai-sites'
		
	),
	'include' => array(
		'lib/custom/src',
		'client/html/src',
		'client/jsonapi/src',
		'controller/common/src',
		'controller/frontend/src',
		'controller/jobs/src',
		'admin/jsonadm/src',
		'admin/jqadm/src',
	),
	'i18n' => array(
		'admin' => 'admin/i18n',
		'admin/jsonadm' => 'admin/jsonadm/i18n',
		'client' => 'client/i18n',
		'client/code' => 'client/i18n/code',
		'controller/common' => 'controller/common/i18n',
		'controller/frontend' => 'controller/frontend/i18n',
		'controller/jobs' => 'controller/jobs/i18n',
		'mshop' => 'lib/custom/i18n',
	),
	'config' => array(
		'config',
	),
	'custom' => array(
		'admin/jqadm' => array(
			'admin/jqadm/manifest.jsb2',
		),
		'admin/jqadm/templates' => array(
			'admin/jqadm/templates',
		),
		'admin/jsonadm/templates' => array(
			'admin/jsonadm/templates',
		),
		'client/html/templates' => array(
			'client/html/templates',
		),
		'client/jsonapi/templates' => array(
			'client/jsonapi/templates',
		),
		'controller/jobs' => array(
			'controller/jobs/src',
		),
		'controller/jobs/templates' => array(
			'controller/jobs/templates',
			'client/html/templates',
		),
	),
	'setup' => array(
		'lib/custom/setup',
	),
);

so through that i added city field successfully
Image
2) i added a decorator Myproject.php in
ext\moudhah\lib\custom\src\MShop\Locale\Manager\Site\Decorator
which contains

Code: Select all

	<?php	
namespace Aimeos\MShop\Locale\Manager\Site\Decorator;
 
 class Myproject extends \Aimeos\MShop\Common\Manager\Decorator\Base implements \Aimeos\MShop\Common\Manager\Decorator\Iface
 {

    
    private $attr = array(
        'city'=> array(
            'code'=>'city',
            'internalcode'=>'mlocsi."city"',
            'label'=>'Site city',
            'type'=> 'string', // integer, float, etc.
            'internaltype'=> \Aimeos\MW\DB\Statement\Base::PARAM_STR, // _INT, _FLOAT, etc.
           
        ),
    );
  
     public function getSaveAttributes() : array
     {
        
         return parent::getSaveAttributes() + $this->createAttributes( $this->attr );
     }
  
     public function getSearchAttributes( $sub = false ) :array
     {
       
         return parent::getSearchAttributes( $sub ) + $this->createAttributes( $this->attr );
     }

    

     
 }
3) i made change in mshop/config file

Code: Select all

<?php

return [
    'locale' => [
		'manager' => [
			
            'site' => [
				'decorators' => [
					'local' => ['Myproject']
				]
			],
			'language' => [
				'decorators' => [
					'local' => ['Myproject']
				]
			]

		],
		

	]
    
];

now when i update a site it successfully updates the value of city
but when i add new value it gives error because when i add die and dump in toarray method

Code: Select all

public function toArray( bool $private = false ) : array
	{
		
		$list = parent::toArray( $private );
		
		
		$list['locale.site.code'] = $this->getCode();
		$list['locale.site.label'] = $this->getLabel();
		$list['locale.site.config'] = $this->getConfig();
		$list['locale.site.status'] = $this->getStatus();
		$list['locale.site.hasChildren'] = $this->hasChildren();
		
		if( $private === true )
		{
			$list['locale.site.level'] = $this->getLevel();
			$list['locale.site.parentid'] = $this->getParentId();
		}

		
		
		
		dd($list);
		return $list;
	}
if gives me

Code: Select all

array:12 [▼
  "locale.site.id" => "15"
  "locale.site.siteid" => "1.15."
  "locale.site.ctime" => "2021-01-16 02:43:28"
  "locale.site.mtime" => "2021-01-26 10:06:08"
  "locale.site.editor" => "info@zsoft.com.pk"
  "locale.site.code" => "nike"
  "locale.site.label" => "Nike"
  "locale.site.config" => []
  "locale.site.status" => 1
  "locale.site.hasChildren" => false
  "locale.site.level" => 1
  "locale.site.parentid" => "1"
]
it is not picking city field which is successfully added in table

but when i add die and dump

Code: Select all

public function fromArray( array &$list, bool $private = false ) : \Aimeos\MShop\Common\Item\Iface
	{
		
		$item = parent::fromArray( $list, $private );

		foreach( $list as $key => $value )
		{
			switch( $key )
			{
				case 'locale.site.code': $item = $item->setCode( $value ); break;
				case 'locale.site.label': $item = $item->setLabel( $value ); break;
				case 'locale.site.status': $item = $item->setStatus( (int) $value ); break;
				case 'locale.site.config': $item = $item->setConfig( (array) $value ); break;
				default: continue 2;
			}

			unset( $list[$key] );
		}
		
		dd($item);
		return $item;
	}

Code: Select all

Aimeos\MShop\Locale\Item\Site\Sites {#1563 ▼
  -deletedItems: []
  -children: []
  -node: Aimeos\MW\Tree\Node\DBNestedSet {#1489 ▶}
  -prefix: "locale.site."
  -available: true
  -modified: true
  #bdata: array:10 [▼
    "locale.site.id" => "15"
    "locale.site.code" => "nike"
    "locale.site.label" => "Nikedfdf"
    "locale.site.status" => 1
    "locale.site.config" => []
    "locale.site.siteid" => "1.15."
    "locale.site.editor" => "info@zsoft.com.pk"
    "locale.site.ctime" => "2021-01-16 02:43:28"
    "locale.site.mtime" => "2021-01-26 10:06:08"
    "city" => "los angeles"
  ]
  -children: []
}
city is there so it updates successfully but not showing in the form and unable to create new one

* one more thing i want to ask when i update a site and do not change default fields and change only field which i
have added it does not update the new field value it only updates when i made changes in default fields.what should i
do update a site when i dont change default field ,ony change custom added fields.note i am using decorator aproach

* second thing is i want to store new field(city) data in uppercase then where should i do

khizar
Posts: 99
Joined: 19 Jan 2021, 09:51

Re: language form-add new field

Post by khizar » 27 Jan 2021, 07:17

aimeos wrote: 26 Jan 2021, 09:38 Rename "locale.language.test" to "test" everywhere, then it will work
please have a look at my problem

khizar
Posts: 99
Joined: 19 Jan 2021, 09:51

Re: language form-add new field

Post by khizar » 27 Jan 2021, 10:30

i am waiting for your reply

khizar
Posts: 99
Joined: 19 Jan 2021, 09:51

Re: language form-add new field

Post by khizar » 28 Jan 2021, 09:04

waiting for reply

khizar
Posts: 99
Joined: 19 Jan 2021, 09:51

Re: language form-add new field

Post by khizar » 29 Jan 2021, 06:35

its been 3 days i posted a question and you guys did not post single reply

User avatar
aimeos
Administrator
Posts: 7866
Joined: 01 Jan 1970, 00:00

Re: language form-add new field

Post by aimeos » 29 Jan 2021, 09:34

khizar wrote: 26 Jan 2021, 10:27 its been 3 days i posted a question and you guys did not post single reply
First of all, there's no guarantee to get a reply to your question at all in the forum. That depends on somebody who has time and knows the answer. If you need immediate support, ask the Aimeos company for help (the Aimeos Open Source project doesn't belong to Norbert's Aimeos company despite of the name). They offer 1:1 support, esp. for their extensions like the ai-sites one you are using:
https://aimeos.com/aimeos-gmbh/contact
khizar wrote: 26 Jan 2021, 10:27 city is there so it updates successfully but not showing in the form and unable to create new one
Hard to say, your code looks correctly. You should add more debug statements to see where the problem might be.
khizar wrote: 26 Jan 2021, 10:27 * one more thing i want to ask when i update a site and do not change default fields and change only field which i
have added it does not update the new field value it only updates when i made changes in default fields.what should i
do update a site when i dont change default field ,ony change custom added fields.note i am using decorator aproach
There was a patch yesterday that fixes that in aimeos/aimeos-core:2020.10.x-dev. You can get it by executing:

Code: Select all

composer req aimeos/aimeos-core:2020.10.x-dev
khizar wrote: 26 Jan 2021, 10:27 * second thing is i want to store new field(city) data in uppercase then where should i do
In that case, you could add a save() method to your manager decorator which receives the item(s) to save. There you can get the value from the item, convert it to uppercase and set it again in the item. Then, call the save() method of the unterlying manager:

Code: Select all

	public function save( $items, bool $fetch = true )
	{
		$items = map( $items )->each( function( $item ) {
			$item->set( 'city', strtoupper( $item->get( 'city' ) ) );
		} );
		return $this->getManager()->save( $items, $fetch );
	}
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

khizar
Posts: 99
Joined: 19 Jan 2021, 09:51

Re: language form-add new field

Post by khizar » 30 Jan 2021, 09:16

aimeos wrote: 29 Jan 2021, 09:34
khizar wrote: 26 Jan 2021, 10:27 its been 3 days i posted a question and you guys did not post single reply
First of all, there's no guarantee to get a reply to your question at all in the forum. That depends on somebody who has time and knows the answer. If you need immediate support, ask the Aimeos company for help (the Aimeos Open Source project doesn't belong to Norbert's Aimeos company despite of the name). They offer 1:1 support, esp. for their extensions like the ai-sites one you are using:
https://aimeos.com/aimeos-gmbh/contact
khizar wrote: 26 Jan 2021, 10:27 city is there so it updates successfully but not showing in the form and unable to create new one
Hard to say, your code looks correctly. You should add more debug statements to see where the problem might be.
khizar wrote: 26 Jan 2021, 10:27 * one more thing i want to ask when i update a site and do not change default fields and change only field which i
have added it does not update the new field value it only updates when i made changes in default fields.what should i
do update a site when i dont change default field ,ony change custom added fields.note i am using decorator aproach
There was a patch yesterday that fixes that in aimeos/aimeos-core:2020.10.x-dev. You can get it by executing:

Code: Select all

composer req aimeos/aimeos-core:2020.10.x-dev
khizar wrote: 26 Jan 2021, 10:27 * second thing is i want to store new field(city) data in uppercase then where should i do
In that case, you could add a save() method to your manager decorator which receives the item(s) to save. There you can get the value from the item, convert it to uppercase and set it again in the item. Then, call the save() method of the unterlying manager:

Code: Select all

	public function save( $items, bool $fetch = true )
	{
		$items = map( $items )->each( function( $item ) {
			$item->set( 'city', strtoupper( $item->get( 'city' ) ) );
		} );
		return $this->getManager()->save( $items, $fetch );
	}

Hi friend,
actually now i have tried another approach by making a file Myproject.php in directory
ext\moudhah\lib\custom\src\MShop\Locale\Manager\Site

Code: Select all

<?php
namespace Aimeos\MShop\Locale\Manager\Site;
 
class Myproject extends Standard
{
    private $searchConfig = array(
        'locale.site.city'=> array(
            'code'=>'locale.site.city',
            'internalcode'=>'mlocsi."city"',
            'label'=>'Product oldcode',
            'type'=> 'string', // integer, float, etc.
            'internaltype'=> \Aimeos\MW\DB\Statement\Base::PARAM_STR, // _INT, _FLOAT, etc.
        ),
    );
	
 public function getSearchAttributes( bool $withsub = true ) : array
    {   
        $list = parent::getSearchAttributes( $withsub );
        
        foreach( $this->searchConfig as $key => $fields ) {
            $list[$key] = new \Aimeos\MW\Criteria\Attribute\Standard( $fields );
        }
       
        return $list;
    }
    protected function createItemBase( array $data = [] ) : \Aimeos\MShop\Locale\Item\Site\Iface
	{
       
		
		return new \Aimeos\MShop\Locale\Item\Site\Myproject( $data );
	}
   
}
after that i added another file Myproject.php in directory
ext\moudhah\lib\custom\src\MShop\Locale\Item\Site

Code: Select all

<?php
namespace Aimeos\MShop\Locale\Item\Site;
 
class Myproject extends Standard
{
    private $myvalues;
 
    public function __construct(array $values)
    {
        parent::__construct($values);
        $this->myvalues = $values;
       
    }
 
    public function getCity()
    {
        if( isset( $this->myvalues['locale.site.city'] ) ) {
            return (string) $this->myvalues['locale.site.city'];
        }
        return '';
    }
 
    public function setCity( $city )
    {
        if ((string) $city !== $this->getCity()) {
            // exit("<br />616");
            $this->myvalues['locale.site.city'] = (string) $city;
            $this->setModified();
        }
        return $this;
    }
 
    public function fromArray( array &$list, bool $private = false ) : \Aimeos\MShop\Common\Item\Iface
    {   
      
        $unknown = [];
        $item = parent::fromArray( $list, $private );

        foreach ($list as $key => $value) {
            switch ($key) {
                case 'locale.site.city':
                    $this->setCity($value);
                    break;
                default:
                    $unknown[$key] = $value;
            }
        }
        // exit("<br />617");
        return $unknown;
    }

    public function toArray( bool $private = false ) : array
	{
		
		$list = parent::toArray( $private );
		
		
		if( $private === true ) {
            $list['locale.site.city'] = $this->getCity();
        }

       
	    return $list;
	}
    
 
   
}
and added following code in my config/mshop.file

Code: Select all

<?php

return [
	'locale' => [
		'manager' => [
			'site' => [
				'name' => 'Myproject',
				'standard' => [
					'insert' => array(
						'ansi' => '
							INSERT INTO "mshop_locale_site" ( :names
								"siteid", "code", "label", "config", "status", "editor",
								"mtime", "ctime", "parentid", "level", "nleft", "nright"
							)
							SELECT :values
								?, ?, ?, ?, ?, ?, ?, ?, 0, 0,
								COALESCE( MAX("nright"), 0 ) + 1, COALESCE( MAX("nright"), 0 ) + 2
							FROM "mshop_locale_site"
						'
					),
					'update' => array(
						'ansi' => '
							UPDATE "mshop_locale_site"
							SET :names
								"siteid" = ?, "code" = ?, "label" = ?, "config" = ?, "status" = ?, "editor" = ?, "mtime" = ?
							WHERE id = ?
						'
					),
					'search' => array(
						'ansi' => '
							SELECT :columns
								mlocsi."id" AS "locale.site.id", mlocsi."siteid" AS "locale.site.siteid",
								mlocsi."code" AS "locale.site.code", mlocsi."label" AS "locale.site.label",
								mlocsi."config" AS "locale.site.config", mlocsi."status" AS "locale.site.status",
								mlocsi."editor" AS "locale.site.editor", mlocsi."mtime" AS "locale.site.mtime",
								mlocsi."ctime" AS "locale.site.ctime",
								mlocsi."city" AS "locale.site.city"
							FROM "mshop_locale_site" AS mlocsi
							WHERE mlocsi."level" = 0 AND :cond
							ORDER BY :order
							OFFSET :start ROWS FETCH NEXT :size ROWS ONLY
						',
						'mysql' => '
							SELECT :columns
								mlocsi."id" AS "locale.site.id", mlocsi."siteid" AS "locale.site.siteid",
								mlocsi."code" AS "locale.site.code", mlocsi."label" AS "locale.site.label",
								mlocsi."config" AS "locale.site.config", mlocsi."status" AS "locale.site.status",
								mlocsi."editor" AS "locale.site.editor", mlocsi."mtime" AS "locale.site.mtime",
								mlocsi."ctime" AS "locale.site.ctime",
								mlocsi."city" AS "locale.site.city"
							FROM "mshop_locale_site" AS mlocsi
							WHERE mlocsi."level" = 0 AND :cond
							ORDER BY :order
							LIMIT :size OFFSET :start
						'
					),
					'count' => array(
						'ansi' => '
							SELECT COUNT(*) AS "count"
							FROM (
								SELECT mlocsi."id"
								FROM "mshop_locale_site" AS mlocsi
								WHERE :cond
								ORDER BY mlocsi."id"
								OFFSET 0 ROWS FETCH NEXT 10000 ROWS ONLY
							) AS list
						',
						'mysql' => '
							SELECT COUNT(*) AS "count"
							FROM (
								SELECT mlocsi."id"
								FROM "mshop_locale_site" AS mlocsi
								WHERE :cond
								ORDER BY mlocsi."id"
								LIMIT 10000 OFFSET 0
							) AS list
						'
					),
					'newid' => array(
						'db2' => 'SELECT IDENTITY_VAL_LOCAL()',
						'mysql' => 'SELECT LAST_INSERT_ID()',
						'oracle' => 'SELECT mshop_locale_site_seq.CURRVAL FROM DUAL',
						'pgsql' => 'SELECT lastval()',
						'sqlite' => 'SELECT last_insert_rowid()',
						'sqlsrv' => 'SELECT @@IDENTITY',
						'sqlanywhere' => 'SELECT @@IDENTITY',
					),
				],
			]

		],
	],
];
i have added the field city successfully and after adding those files i manually entered a value in city field of default site
now when i open site form the list of sites are not showing,you can see in the following picture
Image
when i further investigated i found that there are two files in ai-sites extension
ext\ai-sites\lib\custom\src\MShop\Locale\Manager\Site\Sites.php extends \Aimeos\MShop\Locale\Manager\Site\Standard
ext\ai-sites\lib\custom\src\MShop\Locale\Item\Site\Sites.php extends \Aimeos\MShop\Locale\Item\Site\Standard

Sites.php file is responsible for showing list of sites but when i added my manager and item files in my own extension
which are also extending the standard files from aimeos core the files which are in the ai-sites extension do not work
and it does not show the sites list.

now i am totally stuck at that point please guide me what should i do

User avatar
aimeos
Administrator
Posts: 7866
Joined: 01 Jan 1970, 00:00

Re: language form-add new field

Post by aimeos » 30 Jan 2021, 10:31

Don't extend from the Standard locale site manager class if you are using the ai-sites extension:

Code: Select all

class Myproject extends Standard
Instead, extend from the "Sites" class of that extension:

Code: Select all

class Myproject extends Sites
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

Post Reply