OK, so I have been at this problem for the last few days, and I must admit - I am stuck.
I am trying to make a web application, where users can upload documents or send inbound e-mails.
Each document or email will be added to a stream
. So a stream holds all the docs/mails.
Now, what I want to allow my users are the following:
- Users should be able to add ´fields´ to a stream. A field is essentially just a dynamic variable, that users can set. So for example, if a user uploads a large text file, they can eg. create below
fields
:
id | name
-----------------------
1 | Order number
2 | Tracking reference
Users can then add
parsing rules
to eachfield
. A parsing rule can consist of multiple methods. For example:remove_empty_lines
text_replace
regex_text_replace
Users can apply as many parsing rules to the text string as they want. Everytime a new parsing rule has been applied, the new and updated text string will be stored in parsing_rule_results
OK so above describes the workflow, that a user can setup for each document/email, and above is bound pr. stream
.
Now, what I want to achieve is the following:
- For each new document/email that is added to my application, I need to check what
fields
is defined for the specific stream. - For each field defined, I need to run the string through each
parsing_rule
, and - ultimately, once the string has been run through each parsing rule, the end result should be dynamically saved to that specific document/email. Something like:
id | document_id | email_id | field | data
---------------------------------------------------
1 | 5 | null | 3 | 5000251
2 | 5 | null | 4 | AJIWO4124124J
3 | 6 | null | 3 | 92841
4 | 6 | null | 4 | KKLJPEPQ9102
5 | 6 | null | 3 | E-Order2000
6 | null | 2 | 4 | OOCLTCU8291LK
Which can be translated into:
Stream: 1
Document ID # 5:
order_number
= "5000251"tracking_number
= "AJIWO4124124J"
Document ID # 6:
order_number
= "92841"tracking_number
= "KKLJPEPQ9102"
Email ID # 2:
order_number
= "E-Order2000"tracking_number
= "OOCLTCU8291LK"
Below is the beginning of my database design - but without "field results".
This is the code I have so far (models):
Stream.php
// A stream can have many documents
public function documents()
{
return $this->hasMany(Document::class);
}
//A stream can have many e-mails
public function emails()
{
return $this->hasMany(Email::class);
}
//A stream can have many fields
public function fields()
{
return $this->hasMany(Field::class);
}
//A stream have fields, which then have parsing rules.
public function parsingRules()
{
return $this->hasManyThrough(ParsingRule::class, Field::class);
}
Document.php
//A document belongs to a Stream.
public function stream()
{
return $this->belongsTo(Stream::class);
}
// A document will have fields.
public function fields()
{
return $this->hasMany(Field::class, 'stream_id', 'stream_id');
}
Email.php
// An email belongs to a Stream.
public function stream()
{
return $this->belongsTo(Stream::class);
}
//An email will have fields.
public function fields()
{
return $this->hasMany(Field::class, 'stream_id', 'stream_id');
}
Field.php
// A field belongs to a Stream
public function stream()
{
return $this->belongsTo(Stream::class);
}
// A field can have many parsing rules.
public function parsingRules()
{
return $this->hasMany(ParsingRule::class);
}
ParsingRule.php
//A parsing rule belongs to a field.
public function field()
{
return $this->belongsTo(Field::class);
}
ParsingRuleResult.php
//A parsing rule, belongs to a field rule.
public function fieldrule()
{
return $this->belongsTo(FieldRule::class);
}
// A parsing ruleresult, belongs to a document.
public function document()
{
return $this->belongsTo(Document::class);
}
I believe the real problem I have lies in my understanding of relationships, and how I should dynamically apply above logic.
Let's imagine I have a class, that will be called whenever a new document/email is being added:
ApplyParsingRules.php
public function parse(Stream $stream, Document $document)
{
$text = $document->text;
$fields = $stream->fields()->get();
//1. get all $parsing_rules for each $fields.
//2. parse $text by using each $parsing_rule
//3. save the end result of $text by document/email specific and field.
}
As you can see, I can fetch the stream details as well as the fields for the specific stream.
However - how can I:
- Make it so it allows both Email and Document, depending on what is being added? (Above only allows Document)
- Run through each field, and subsequently parse through each parsing_rule and save the end result, so it's specific for each document/email
I hope above is somewhat clear. This post got a lot longer than first expected.