Skip to content
This repository has been archived by the owner on Jan 21, 2020. It is now read-only.

FB-113 Site settings in DB - stage 1 #2460

Closed
wants to merge 18 commits into from

Conversation

fvovan
Copy link
Contributor

@fvovan fvovan commented Dec 12, 2016

We need to split it into 2 parts in order migrate existing configuration properly.
This PR will contain schema changes, model classes and other functionality to allow migration, example application data and settings editor.
The second one will actually use these settings

@fvovan fvovan self-assigned this Dec 12, 2016
@fvovan fvovan added the slack label Dec 12, 2016
@fvovan
Copy link
Contributor Author

fvovan commented Dec 12, 2016

I'm not quite sure I chose best naming conventions here. CM_Site_SiteSettings looks similar to existing CM_Site_SiteFactory but may be it's not the best option.
The same is for configuration field of table. Besides it turned out we can't avoid using autoincrement ID value for models, so siteId was created. Also we discussed classType column creating, but now I doubt how it could be used considering CM_Site_Abstract->getId() is equal by definition to CM_Site_Abstract->getType().

@njam , @tomaszdurka could you have a look please while i'm preparing the second part?

Copy link
Member

@njam njam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some small notes.

Let's discuss on a call, will send invite.

* @param $type
* @return string|null
*/
public static function findClassName($type) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to be unused

/**
* @return int
*/
public function getConfigurationSize() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused?

/**
* @return string|null
*/
public function findSiteClassName() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please see comment for CM_Site_Abstract::findClassName()

if (!$this->_has('configuration')) {
return CM_Params::factory([]);
}
$paramsEncoded = CM_Params::jsonDecode($this->_get('configuration'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use CM_Util::jsonDecode() instead

* @param CM_Params $configuration
*/
public function setConfiguration(CM_Params $configuration) {
$this->_set('configuration', CM_Params::jsonEncode($configuration->getParamsEncoded()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use CM_Util::jsonEncode() instead


protected function _getSchema() {
return new CM_Model_Schema_Definition([
'siteId' => ['type' => 'int', 'optional' => true],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it optional?

protected function _getSchema() {
return new CM_Model_Schema_Definition([
'siteId' => ['type' => 'int', 'optional' => true],
'name' => ['type' => 'string', 'optional' => true],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make the name mandatory?

* @param int $siteId
* @return CM_Site_SiteSettings|null
*/
public static function findBySiteId($siteId) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about keeping the same ID values for "site" and "site-settings"?
Then this would not be needed?

@@ -592,6 +592,27 @@ public static function jsonDecode($value) {

/**
* @param string $value
* @return bool
*/
public static function jsonIsValid($value) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused?

@fvovan
Copy link
Contributor Author

fvovan commented Dec 23, 2016

this was simplified.
@njam please review

Copy link
Member

@njam njam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some functions I couldn't find usages. Maybe they will be used later? It seems the PR for stage 2 is not up to date, so I wasn't able to tell.

*/
public static function getAll() {
$siteList = array();
foreach (CM_Config::get()->CM_Site_Abstract->types as $className) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iirc we wanted this to use the database table, so that we could potentially have database-only sites in the future?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, you're right, but now we need to keep it in order to perform settings migration.

* @param $type
* @return string|null
*/
public static function findClassName($type) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is only used in findSiteClassName(), which could be using just get_class() and is itself unused. Can this be removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. the thing is we need (well, actually it's not strictly need) to get site class name only by CM_Site_SiteSetting::type_id.
we don't have site instance there to use get_class(). But on the other hand the only usage is admin UI we can omit it there and rather output another text label.

* @return CM_Params
*/
public function getConfiguration() {
if (!$this->_has('configuration')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? The field is mandatory, so it should always be present?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh. good catch

* @param string $key
* @param string $value
*/
public function upsertConfigurationValue($key, $value) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the use case for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Saving settings values in forms. Besides originally inserting of settings key was supported, but actually it works the same.


protected function _getSchema() {
return new CM_Model_Schema_Definition([
'siteType' => ['type' => 'int', 'optional' => true],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it optional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's connected to the fact that sometimes we create settings before even have any site class. Mostly it happens in tests. Yep, code intended only for tests is obviously a code smell. And i'm not quite sure how best to proceed here. In fact the only purpose of cm_site_setting.siteId is mapping for CM_Site_Abstract::getAll(). That's why maybe it would be a good idea to have "not persisted setting" class. So theoretically we'll be able to create sites with settings which are not in the DB.

$configuration = CM_Params::factory([]);
}
$siteSettings = new self();
$siteSettings->_set([
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use the setters instead, this way we can avoid duplicating some code ( jsonEncode()).

`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`siteType` int(10) unsigned DEFAULT NULL,
`name` varchar(32) NOT NULL,
`configuration` varchar(2000) NOT NULL,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should make it larger. We might potentially store a lot of strings in here. And since this table is small and this field is not indexed it doesn't matter for performance. 65535?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I set it to 21800. (maximum value for utf-8 is 21844 but for some reason it breaks tests)

`configuration` varchar(2000) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `siteType` (`siteType`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use InnoDB for this new table where performance considerations don't matter?

@@ -0,0 +1,19 @@
<?php
class CM_Paging_SiteSettings_AllTest extends CMTest_TestCase {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

newline

$settingsAdded = CM_Site_SiteSettings::create(1, 'Baz', CM_Params::factory(['bar' => 'foo']));
$paging = new CM_Paging_SiteSettings_All();
$this->assertSame(1, $paging->getCount());
$settings = $paging->getItem(0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A more concise way of asserting pagings is:

$this->assertEquals([$item1, $item2], $paging);

@njam
Copy link
Member

njam commented Jan 2, 2017

I think it would be good to implement getters and setters on the site class(es) for the different fields, e.g. getSupportEmail(), and have a strict schema for them.
Doing that in the SiteSettings model would be great, as we could re-use the existing schema mechanism, but it would mean that we'd need to have separate SiteSettings models in SK and in CM.

Alternatively we could just implement getters and setters with casting on the Site model, which would access the data on the SiteSettings with generic functions accessing the data bag.
@tomaszdurka @fvovan wdyt?

@njam
Copy link
Member

njam commented Jan 18, 2017

As discussed: maybe it's better to make the Site extend Model so we can reuse schema and persistence functionality.
Vladimir will prepare a new branch with how the final logic could look in CM. Then we can compare it and decide which way to go.

@njam njam changed the title Site settings in DB - stage 1 FB-113 Site settings in DB - stage 1 Feb 26, 2017
@njam njam unassigned fvovan Mar 20, 2017
@fvovan
Copy link
Contributor Author

fvovan commented Jun 27, 2017

@fvovan fvovan closed this Jun 27, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants