PHP array and JSON schema - jsonschema

Many times I have had this scenario in php where I have a data structure but it is hard to work with because PHP doc cannot handle it.
<?php
/** #var (??) $contact */
$contact = array(
"firstName" => "John",
"lastName" => "doe",
"age" => 26,
"address" => array(
"streetAddress" => "naist street",
"city" => "Nara",
"postalCode" => "630-0192"
),
"phoneNumbers": [
array(
"type" : "mobile",
"number": "333 444 5566"
), array(
"type" : "home",
"number": "333 222 1100"
)
]
}
Perhaps PHPDoc can handle it and I just don't know how. But at least JSON Schema sounds like a great choice for documenting structures like that, and JSON objects always can be mapped 1:1 to php arrays, so here is the question:
Is there a way to document a data structure, in an IDE like PhpStorm, in a way that I would get correct type help when typing something like this?:
$contact["phoneNumbers"][0]["type"]
It is ok if the solution is not with JSON Schema, PHP doc would be enough if it could go so deep in structure.
Oh, and creating a class Contact {} and a class PhoneNumber {} is not feasible because the structure is not as simple as the one I mentioned here, and it would be an overkill to write all those classes just for type hinting.
Thanks in advance for your help!
JSON Schema: https://json-schema.org/learn/getting-started-step-by-step.html

Related

Laravel-Validation of unknown array keys

I have created a controller to validate and save a form.
I don't know how the individual form fields are named because this is assigned by the system in the form designer.
For this reason I first make a query ($valArrays) to find out which fields are required and then find out what the array key is.
The field order_title is always required.
$valArrays = FormDetail::where('form_details.form_id', $request->form_id)
->where('required', 'yes')
->get();
$array = array();
$array['order_title'] = 'required';
foreach ($valArrays as $valArray) :
$array[$valArray->detail_id] = 'required';
endforeach;
$request->validate($array);
when I query via dd($array) I get the following evaluation:
^ array:6 [▼
"order_title" => "required"
"QS0brKe5LP" => "required"
"TjFusWAKLh" => "required"
"uNqAPbNwkg" => "required"
"OvclFtOlvF" => "required"
"52e515mfRf" => "required"
]
so everything is ok! but the programme jumps back to the form without saving.
If I take out the code part everything works but without validation :0(
Do you have any idea why this could be?

Wordpress: Wp_Query - find posts with meta_query OR tax_query

I want to find posts which have a specific post meta key/value or posts which are in a specific category. Here is the query. I want to combine the tax_query and the meta_query with OR, but AFAICS there's no way to do this.
$args = [
'post_type' => 'my-event',
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
'cat' => 'home',
'tax_query' => [
[
'taxonomy' => 'event-cat',
'terms' => [
'open',
],
'field' => 'slug',
'operator' => 'IN',
'include_children' => true,
],
],
'meta_query' => [
[
'key' => 'event_author',
'value' => [1,7,11,15],
'compare' => 'IN',
],
],
];
$loop = new WP_Query($args);
Result should be:
All posts (events) which are in the category 'open' (no matter who the author is) AND all posts which are from one of the specified authors (no matter in which category the event is).
On SO I found a few similar questions and I think I have to create a SQL query to find a solution but I don't know how to do it. Hope that someone can help me here.
Thanks and best regards.
In order to make custom,unconventional and a bit complicated queries like this, you have to learn some basic SQL Syntax. Trust me, SQL basics are not so hard to learn, and they are really worth it if you consider how many projects in many different programming languages need some SQL knowledge.
WordPress gives you the option to make custom queries with wpdb::get_results() function. In case you already know how to use SQL syntax, try exploring the wordpress database a little, and you will find what table columns you need to extract to get the result you want.

How to setup ElasticSearch to do SQL LIKE "%" for email addresses?

In SQL, I can search email addresses pretty well with SQL LIKE.
With an email "stack#domain.com", searching "stack", "#domain.com", "domain.com", or "domain" would get me back the desired email address.
How can I get the same result with ElasticSearch?
I played with nGram, edgeNGram, uax_url_email, etc and the search results have been pretty bad. Please correct me if I'm wrong, it sounds like I have to do the following:
for index_analyzer
use "keyword", "whitespace", or "uax_url_email" tokenizer so the email don't get tokenized
but wildcard queries don't seem to work (with tire at least)
use "nGram" or "edgeNGram" for filter
I always get way too many unwanted results like getting "first#domain.com" when searching "first-second".
for search_analyzer
don't do nGram
One experiment code
tire.settings :number_of_shards => 1,
:number_of_replicas => 1,
:analysis => {
:filter => {
:db_ngram => {
"type" => "nGram",
"max_gram" => 255,
"min_gram" => 3 }
},
:analyzer => {
:string_analyzer => {
"tokenizer" => "standard",
"filter" => ["standard", "lowercase", "asciifolding", "db_ngram"],
"type" => "custom" },
:index_name_analyzer => {
"tokenizer" => "standard",
"filter" => ["standard", "lowercase", "asciifolding"],
"type" => "custom" },
:search_name_analyzer => {
"tokenizer" => "whitespace",
"filter" => ["lowercase", "db_ngram"],
"type" => "custom" },
:index_email_analyzer => {
"tokenizer" => "whitespace",
"filter" => ["lowercase"],
"type" => "custom" }
}
} do
mapping do
indexes :id, :index => :not_analyzed
indexes :name, :index_analyzer => 'index_name_analyzer', :search_analyzer => 'search_name_analyzer'
indexes :email, :index_analyzer => 'index_email_analyzer', :search_analyzer => 'search_email_analyzer'
end
end
Specific cases that don't work well:
emails with hyphen (eg. email-hyphen#domain.com)
query string '#' at the beginning or end
exact matches
searching with wildcard like '#' gets very unexpected results.
Suppose I have, "aaa#email.com", "aaa_0#email.com", and "aaa-0#email.com, searching "aaa" gives me "aaa#a.com" "aaa-0#email.com. Searching "aaa*" give me everything, but "aaa-*" gives me nothing. So, how should I do exact match wildcard queries? For these type of queries, I get pretty much the same results for different tokenizer/analyzer.
I do these after each mapping change:
Model.tire.index.delete
Model.tire.create_elasticsearch_index
Model.tire.index.import Model.all
References:
Configure ElasticSearch to use ngram by default. - SQL LIKE %% behavior
http://euphonious-intuition.com/2012/08/more-complicated-mapping-in-elasticsearch/
Considering what you are trying to accomplish, KeywordAnalyzer might be a reasonable choice of analyzer, though I don't see anything that would cause problems with a WhitespaceAnalyzer.
I suspect you are running into problems with the query parsing and analysis, although you haven't really described how you are querying. Simplest case would be to simply use term or prefix queries.
It does seem a bit like StandardAnalyzer would serve your purpose here, mostly (differentiating between "aaa_0" and "aaa-0" would be a problem), as long as it is applied consistently, and your query is correct.

Tiered? structure of complex Zend Framework models/objects

What is the best way to store complex models in ZF? In the example below, should each attribute be a separate model entirely, or should the item be a multi dimensional array (as shown below)?
object(Application_Model_Item)#79 (4) {
["_id":protected] => int(45)
["_name":protected] => string(5) "Bolts"
["_description":protected] => NULL
["_attributes":protected] => array(2) {
[0] => array(2) {
["id"] => string(1) "3"
["name"] => string(4) "Size"
}
[1] => array(2) {
["id"] => string(1) "4"
["name"] => string(6) "Length"
}
}
Thanks in advance.
It all depends on your use case:
Indexing by ID or Position:
If you would like speed when accessing a particular attribute, then index the attributes by their IDs instead of their index position.
If you would like to keep an order, then order them by index position and a position offset amount.
Independent Table Vs Local Array:
If the attributes are duplicated in multiple items, then have them as their own table, and reference the attributes to that table.
If the attributes are not refenced and are unique to each item, then using them as serialise-able arrays (for storage) is adequate than needing them to be their own table.
In the case of _attributes i would use array of objects.
So it attributes would be an array of new model Attribute()
I make a class for every business model entity
["_attributes":protected] => array(2) {
[0] => Object(Model_Attribute) {}
[1] => Object(Model_Attribute) {}
}
class Model_Attribute {
protected $id;
public function getId();
public function setId($id);
.
.
.
}
I suggest you look at Doctrine ORM 2.0 since it can support the design from the above.
Look at this page, it may give you a clue:
http://www.doctrine-project.org/projects/orm/2.0/docs/reference/association-mapping/en

How do I create a nested has_many or belongs_to relationship with DBIx::Class?

In my code I have three classes as follows: Forum, Forum::Thread and Forum::Post
What I want to do is create a belongs_to-relationship from the Forum::Post class to the Forum class and vice versa with a has_many, preferably without creating a custom function for it. (This is admittedly more of an intellectual exercise than a technical limitation or actual problem, but if it is possible, I would much like to know.)
The commented out lines contain my intention with the relationships, but in their current form, they fail to work. I've poked around in the documentation, but cannot find anything relevant to this specific case.
Any pointers?
The forum class:
package Schema::Result::Forum;
use Moose;
extends qw/DBIx::Class/;
__PACKAGE__->load_components (qw/Core/);
__PACKAGE__->table ('forum');
__PACKAGE__->add_columns (
id => {
is_auto_increment => 1,
data_type => 'integer',
},
);
__PACKAGE__->set_primary_key ('id');
__PACKAGE__->has_many (threads => 'Schema::Result::Forum::Thread');
#This is the interesting line
#__PACKAGE__->has_many (posts => 'threads' => 'forums' );
1;
The thread class:
package Schema::Result::Forum::Thread;
use Moose;
extends qw/DBIx::Class/;
__PACKAGE__->load_components (qw/Core/);
__PACKAGE__->table ('forum_thread');
__PACKAGE__->add_columns (
id => {
is_auto_increment => 1,
data_type => 'integer',
},
forum => {
data_type => 'integer',
},
);
__PACKAGE__->set_primary_key ('id');
__PACKAGE__->belongs_to (forum => 'Schema::Result::Forum');
__PACKAGE__->has_many (posts => 'Schema::Result::Forum::Post');
1;
The post class:
package Schema::Result::Forum::Post;
use Moose;
extends qw/DBIx::Class/;
__PACKAGE__->load_components (qw/Core/);
__PACKAGE__->table ('forum_post');
__PACKAGE__->add_columns (
id => {
is_auto_increment => 1,
data_type => 'integer',
},
thread => {
data_type => 'integer',
},
);
__PACKAGE__->set_primary_key ('id');
__PACKAGE__->belongs_to (thread => 'Schema::Result::Forum::Thread');
#This is the other interesting line
#__PACKAGE__->belongs_to (forum => 'thread' => 'forum');
1;
PS: Additional columns to hold actual content were omitted for brevity.
It looks like nested relationships aren't possible. has_many takes a single foreign class, which has a foreign key to the calling class.
The good news is $forum->threads->posts returns a single DBIx::Class::Resultset. It is not translated into SQL until needed, so when you call $forum->threads->posts->all() or even something like $forum->search_related('threads',{},{rows=>25})->posts->all(), it only runs a single query.
If your goal is to have a $post->forum, it can always be a method: sub forum{$_[0]->thread->forum}
What database and engine-type are you using? If you don't have foreign keys (like, for instance, with myisam tables in MySQL) then you'll have to provide the column names in your relationship statements.