Set default value for allowMultipleNulls to TRUE - cakephp

I think I am missing something.
In CakePHP 4.2 the new option allowMultipleNulls was added. The default value is FALSE. Is there a way to set it to TRUE for the whole project?
With this option I finally can save NULL values in unique fields without any effort.
Currently I have edited the line #39 in cakephp/cakephp/src/ORM/Rule/IsUnique.php and set it to TRUE but this is the death penalty as with the next CakePHP update this gets overwritten.

Currently CakePHP doesn't offer a simple way to set the default value to TRUE. I opened a new issue regarding this and now they are discussing about some principal questions and how to implement it in the most complicated way.
My point of view is that each underlying database engine accepts NULL in a unique index but CakePHP is baking here something completely strange and different.
In CakePHP 4.x it was removed and in CakePHP 4.2 it was re-introduced again but with the default FALSE.
However, as it may take ages until they implement a very simple method to set the default value to TRUE I am using the below few lines of code. The point is that the next CakePHP update overrides my modification in their source code and this breaks then my project.
Therefore I check each time in app_local.php the current default value of allowMultipleNulls and when it isn't TRUE then the project dies with a notification. A responsible developer isn't running an update while the business hours and tests after the update the site, so this solution is working for me very reliable without bothering the users. I can live with the very small delay which needs the execution of the code.
$voidIsUnique = new \Cake\ORM\Rule\IsUnique( [], [] );
$isUnique = new ReflectionClass(\Cake\ORM\Rule\IsUnique::class);
$property = $isUnique->getProperty("_options");
$property->setAccessible(TRUE);
if ( !$property->getValue($voidIsUnique) ["allowMultipleNulls"] ) {
die('<span style="background-color: black; color: yellow; font-size: 36px;">' .
'IsUnique::_options ["allowMultipleNulls"] is FALSE. Fix the source code!</span>');
}
$property->setAccessible(FALSE);
Once CakePHP team implemented something I will update it here.

Related

Set default date for zul datebox

I inherited a legacy website written in old zul and have to add new datebox component for birthday datepicker.
Have added a constraint to accept dates before a given date but that triggers an error alertbox from start as the date presented/selected by default on the datepicker is today.
I wouldn't want to use a workaround but to all due respect it seems like this is something over the top feature I'm looking for in zk's reality:
The main showcase for zul does include a birthday datebox, but pretty lame as it doesn't contain any constrain on age.
There is zk fiddler to show how the before constrain works, but that just proves my point that it doesn't select the first proper date for default date at least, if there is no clean way of setting it.
There is forum post that proposes a workaround to set the default year, so Zk is most probably incapable of doing this without a workaround.
There is an open ZK Jira issue from 2017 that addresses somewhat this issue, with a proposed solution pretty much the same as the workaround mentioned in the above point - so the hope is kinda lost, have to go on the workaround route.
I did try that workaround (after the forum post, as that has default year), but the workaround doesn't work for me. It does execute the
this.setValue(initialDate);
And I see that the value is set into the datebox's _pop/_value and _pop/_end nodes but no difference is visible on the datepicker box, still today is preselected altough it is greyed out - so no effect.
Still, when I try it in a fiddle with version 6.5.8.1, the oldest engine that exists, it does work, but not locally with v5.0.11.
In the buglist for this version there is no mention of datebox. Tried to look into to some bugs that might be interfering but turns out it was just another episode of me wasting time with this.
Tried in the 5.0.11 sandbox and it doesnt work with that version. The structure of how I use it is imitated in the linked fiddler. Hints on a workaround that works on this version?
ZK 5.0.11 is a bit on the older side currently, so it might not accept exactly the same overrides as later versions. If I understand the issue correctly, it boils down to either
1 - setting a value before Datebox is rendered to have a "initial date" opened in calendar.
I'd say that's the easy way out, since you can use either composing or databinding to set the value of the datebox during page rendering. Here's a small sample using databinding and zscripts, but the same logic should apply from composer with setValue(). You mentioned that this doesn't work for you locally with 5.0.11 though. Can you share the code that you are using for this? Sample code here in fiddle I can run it on local 5.0.11, and it set the date before popup is opened.
or
2 - setting an initial date (which doesn't affect the selected value) but would be the target for the opened calendar.
This is not a default ZK 5 behavior for datebox. If you want that effect, you would need to customize it using an override script. Simplest way in can think of in ZK 5 is to use the open event of the datebox popup here's an example of what it would look like (package in a script tag in a single page for the example, would use a global js file for real deployement) example here

How to list all datasets in CKAN (not only the active ones)

I am working on a project based on CKAN, and I am required to list in a page all the datasets that have the state "active" and "draft". When you go to the datasets page, you can only see the ones that have the state marked as "active", but not "draft".
If I use the API (call the package_list() method) or REST calls (http://localhost/api/3/action/package_list), CKAN only returns "active" datasets, but not "drafts". I double and triple checked the documentation, and apparently one cannot lists the datasets by their state.
Does anybody have a clue on how to do this? Has anybody done this already?
Thanks!
If nothing else, you could write an extension to do this. The database call itself will be pretty simple:
SELECT id,title,name FROM package WHERE state='active' OR state='draft';
I managed to modify CKAN core to list the datasets that do not have the state "draft" or "deleted", and it works, but I do no want to touch CKAN's core, I want to do this using a plugin, so the normal thing to do is to implement plugins.IActions and override the package_list method with a custom one. I have already written my own extension to try to modify CKAN behavior on method package_list(), but I can't seem to figure it out how to make it work.
Here is my code:
#side_effect_free
def package_list_custom(context, data_dict=None):
datasets = []
dataset_q = (model.Session.query(model.Package)
.join(model.PackageRole))
for dataset in dataset_q:
if dataset.state != 'draft' and dataset.state != 'deleted':
datasets.append(dataset)
return [dataset.id for dataset in datasets]
class Cnaf_WorkflowPlugin(plugins.SingletonPlugin):
plugins.implements(plugins.IActions)
def get_actions(self):
return {
'package_list' : package_list_custom
}
If I modify CKAN core it works very well, but the problem is that I am not to touch it, so I am obliged to do it via an extension.
EDIT: Ok, I managed to make it work, you need to decorate the method with #side_effect_free. I modified my code, and now it works.
The package_search API is capable of this, by searching for state:draft and setting the include_drafts=True flag. Something like this:
https://my-site.com/api/action/package_search?q=state:draft&include_drafts=True
You should be able to access this from a plugin with something like: ckan.plugins.toolkit.get_action('package_search')(context=context, data_dict={'q': 'state:draft', 'include_drafts': True}) (you'll need to assemble the context yourself, containing a 'user' key for the current username and a 'userobj' key for the current user object).
Then make a page from the results.

Drupal: D7 rewriting values returned by views

I have a requirement to perform an indexed search across content which must include a couple of tags in the result. The tags must be a random selection. The platform is Drupal 7.12
I have created a view that manages the results of a SOLR search through the search_api. The view returns the required content and seems to work as intended. I have included a couple of Global: custom text fields as placeholders for the tag entries.
I am now looking for a solution to manage the requirement to randomise the tag values. The randomisation is not the issue, the issue is how to include the random values into the view result.
My current approach is to write a views_pre_render hook to intercept the placeholders which appear as fields ([nothing] and [nothing_1]). The test code looks like the following
function MODULE_views_pre_render( &$view )
{
$view_display = $view->display['default'];
$display_option = $view_display->display_options;
$fields = $display_option['fields'];
foreach( $view->result as $result )
{
$fields['nothing']['alter']['text'] = sprintf("test %d", rand(1,9));
}
}
I am currently not seeing any change in the placeholder when the view is rendered.
Any pointers to approach, alternate solutions etc would be gratefully received as this is consuming a lot of scarce time at the moment. Calling print_r( $view ) from within the hook dumps over 46M into a log file for a result set of 2 items.
There are two possible solutions for your task.
First approach is do everything on the template level. Define a template for the view field you want to randomize. In advanced settings of your display go to Theme: Information. Make sure that the proper theme is selected and find the template suggestions for your field. They are listed starting from most general to the most specific and you can choose whatever suits you better.
I guess the most specific template suggestion for your field would be something like this: views-view-field--[YOR VIEW NAME]--[YOUR DISPLAY NAME]--nothing.tpl.php. Create the file with that name in the theme templates directory and in this template you can render what ever you want.
By default this template has only one line:
print $output;
you can change this to:
print sprintf("test %d", rand(1,9));
or to anything else, whatsoever :)
Second approach is to go with Views PHP module. WIth this module you can add a custom PHP field in which you can do whatever you want. Even though the module hasn't been released it seems to work quite well for the most of the tasks and most certainly for such a simple task as randomizing numbers it will work out for sure.
I stumbled upon this while searching for another issue and thought I would contribute.
Instead of adding another module or modifying a template, just add a views "sort criteria" of "Global: Random".

Storing a textarea's value into a database table

How can you get the value of a <textarea> and store it in a MySQL database table?
I'm using TinyMCE 3.3.9.3.
Seeing as no one has answered your question I thought I'd chip in. Have you ever managed to get any form data passed into a database before (I.E is it just accessing a textarea that's the problem), or is this a general question about how to put form data into databases?
One thing I would strongly recommend is moving away from WYSIWYG style editors if your seriously considering doing web development properly. From experience no matter how good they claim to be you'll always encounter cross browser problems and at some point you'll have to dig into the code and understand it.
Sorry this isn't a direct answer, but with a bit more info as to what you need to know I'm sure we can help... I warn you though, if you've not had much experience at this some of the answers could be a bit deep. I think maybe this is why you've not had any responses because the answer require could potentially be quite epic,lol.
Dan
The tinymce editor id equals the textarea id.
Assuming that editor is your tinymce editor instance you may use the following to get the textareaa content (which is then equal to the editor content).
editor.triggerSave(); // update the textarea
var textarea_element = document.getElementById(editor.id); // get the updated textarea
var content = textarea_element.innerHTML; // this is the content
// now you need to call a script to save the content (i suggest you use ajax)
...

How do I automatically change the assignee of a bug back to the reporter when a bug is marked RESOLVED?

We have a workflow where all incoming bugs are marked ASSIGNED to their product's default assignee, then they stay in ASSIGNED until RESOLVED by the assignee.
At that point, they go either from RESOLVED back to ASSIGNED (e.g. not done yet) or to CLOSED once they reporter is satisfied.
How do we automatically change the assignee of the bug to the reporter when the first assignee marks it RESOLVED?
Actually, this is pretty easy with Bugzilla hooks. Where the extension code needs to go will depend on what version you are using, because this is a capability that's rapidly developing.
In Bugzilla 3.6.1, the current version, if you wanted to call your extension Local, you would create a file extensions/Local/Extension.pm.
http://www.bugzilla.org/docs/3.6/en/html/api/Bugzilla/Extension.html is the overview of the whole extension system.
The hook you want to use for this is bug_end_of_update, which is called in Bugzilla/Bug.pm after the object is changed but before it is written to the database.
For what you're doing, you should probably check changes to see whether bug_status has changed. If so, update bug to set the owner to the reporter, and add that change to changes.
The main developers of Bugzilla can usually be found on #mozwebtools on irc.mozilla.org, drop in and chat them up about the particulars if my answer isn't enough to get you rolling.
This will work: (CustomExtension.pm)
package Bugzilla::Extension::CustomExtension;
use strict;
use base qw(Bugzilla::Extension);
our $VERSION = '1.0';
use constant NAME => 'CustomExtension';
sub object_end_of_set_all {
my ($self, $args) = #_;
my $object = $args->{'object'};
if ($object->isa('Bugzilla::Bug')) {
if ($object->{'bug_status'} eq 'RESOLVED') { # Bug has been RESOLVED
$object->{'assigned_to'} = $object->{'reporter_id'}; # re-assign to Reporter
}
}
}
__PACKAGE__->NAME;

Resources