Jump to content

Developing FieldtypeFloatLanguage


Karl_T
 Share

Recommended Posts

I am currently cloning core text language field into float field as I want to use the multi-language function as a multinational solution. I am using the float field as price field, since the price is different for different country(language). Below is my trial, unfortunately a failed one. Any value will be saved as zero or null in database. I would like some advises on this. Thanks.

EDIT: please ignore the below code. Updated code has been posted in reply

Spoiler

 

 

Link to comment
Share on other sites

you could also use my handsontable module to create an input for each language and then query the column based on the language code and return the price. the module is alpha and you have to be careful when changing settings after field setup as data may bet lost, but maybe it's worth a try.

 

  • Like 1
Link to comment
Share on other sites

Thanks for letting me know your great module. The module is really handy and fit for many use case. I have waited long to see excel like inputfield like this one as I do not have the ability to make one as I am not good at database.

The case I encounter is that I need the permission control over the price for different country. I think it would be the best to make the field multi-language enabled.

Below is the update. Only default language is saved correctly, while other languages are still null if I saved any value into them. The issue is that the sanitizeValue() input $value is always null for other languages, while sleepValue() $value is good. I cannot find where the value get removed.

<?php namespace ProcessWire;

require_once(wire('config')->paths->root . 'wire/modules/LanguageSupport/FieldtypeLanguageInterface.php'); 

/**
 * Multi-language capable float field
 *
 * ProcessWire 3.x, Copyright 2016 by Ryan Cramer
 * https://processwire.com
 *
 *
 */

class FieldtypeFloatLanguage extends FieldtypeFloat implements FieldtypeLanguageInterface {

	public static function getModuleInfo() {
		return array(
			'title' => 'Float (Multi-language)',
			'version' => 0,
			'summary' => 'Field that stores a floating point (decimal) number in multiple languages',
			'permanent' => false,
			'requires' => array('LanguageSupportFields'),
			);
	}

	/**
	 * Sanitize value for storage
	 * 
	 * @param Page $page
	 * @param Field $field
	 * @param LanguagesValueInterface|float $value
	 * @return LanguagesPageFieldValue
	 *
	 */
	public function sanitizeValue(Page $page, Field $field, $value) {
		foreach($value as $languageName => $languageValue) {
			$languageName = $this->wire('languages')->get($languageName)->name;
			if(!strlen("$languageValue")) $value->$languageName = '';
			if(!is_float($languageValue) && !is_int($languageValue)) {
				$value->$languageName = $this->wire('sanitizer')->float((string) $languageValue, array('blankValue' => ''));
			}
			if(is_null($field->precision)) {
				$value->$languageName = (float) $languageValue;
			} else {
				$value->$languageName = round((float) $languageValue, $field->precision);
			}
		}
		return $value;
	}


	/**
	 * Return the database schema in specified format
	 * 
	 * @param Field $field
	 * @return array
	 *
	 */
	public function getDatabaseSchema(Field $field) {
		$schema = parent::getDatabaseSchema($field);
		$languageSupport = $this->wire('modules')->get('LanguageSupport'); 
		foreach($languageSupport->otherLanguagePageIDs as $languageID) {
			$schema['data' . $languageID] = 'float';
			$schema['keys']["data{$languageID}"] = "KEY `data{$languageID}` (`data{$languageID}`)";
		}
		return $schema;
	}

	/**
	 * Format value for output, basically typecasting to a float and sending to textformatters from FieldtypeFloat
	 * 
	 * @param Page $page
	 * @param Field $field
	 * @param LanguagesValueInterface|float $value
	 * @return float
	 *
	 */
	public function sleepValue(Page $page, Field $field, $value) {
		$precision = $field->precision; 
		foreach($value as $languageName => $languageValue) {
			$languageName = $this->wire('languages')->get($languageName)->name;
			if(is_null($precision)) $precision = self::getPrecision($languageValue); 
			if(!is_string($languageValue)) $value->languageName = number_format($languageValue, $precision, '.', '');
		}
		return $value; 
	}
}

 

  • Like 1
Link to comment
Share on other sites

Thanks for sharing this!

Btw., you could save a few characters where you check if the language in the loop is the default language by simply calling $language->isDefault(), and perhaps also eliminate doubled code.

// Lines 85...89
			$dataname = $language->isDefault() ? 'data' : 'data' . $language->id;
			if(!is_string($languageValue)) $sleepValue[$dataname] = number_format($languageValue, $precision, '.', '');

 

  • Like 2
Link to comment
Share on other sites

  • 2 months later...

Thanks for your suggestion! It is weird that I didn't follow my own post.

I am having an error when a new page is generated in admin(new > enter title and name > save > error). It is an error related to database which is my weakness(thanks to Processwire I do not have to deal with it on my own). Could anyone help taking a look? github

Session: Error saving field "price" - SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1

 

Link to comment
Share on other sites

16 hours ago, Karl_T said:

I am having an error when a new page is generated in admin(new > enter title and name > save > error). It is an error related to database which is my weakness(thanks to Processwire I do not have to deal with it on my own). Could anyone help taking a look? github

For now, a simple else for the !is_string() check in sleepValue() will get rid of it. It will mean, though, zeroes saved to DB for any blank values.

if(!is_string($languageValue)) $sleepValue[$dataname] = number_format($languageValue, $precision, '.', '');
else $sleepValue[$dataname] = NULL;// or '' or 0

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...