#StackBounty: #php #html How to wrap multiple groups of LIs within a string with ULs in php

Bounty: 50

I get data (strings with some html) from different sources I can’t influence. The strings contain (but are not limited to) LI elements that are visually grouped – but miss parent UL elements. I need to wrap the groups of LI tags with a UL tag.

This works fine if there is only one group of LI elements within a string. I can easily use DOMDocument, search the LI tags and wrap them with a newly created UL tag. Unfortunately there can be multiple groups and the separation of the groups isn’t defined – but is always some kind of text or a html tag. It’s easily to recognize the groups as a human 🙂

So logically speaking I would need to find an opening <li> as the starting point of a group and a closing </li> that isn’t followed by another opening <li> as the end point, ignoring all white spaces.

An example source string could be:

Some text
<strong>Some other text</strong>
<li>Element A1</li><li>Element A2</li>
<li>Element A3</li>
Text that separates group A from group B
<li>Element B1</li>

<li>Element B2</li> <li>Element B3</li>
<li>Element B4</li>
<strong>Element that separates group B from group C</strong>
<li>Element C1</li>
<li>Element C2</li>
Text can follow. 

The desired result would be

Some text
<strong>Some other text</strong>
<ul>
  <li>Element A1</li><li>Element A2</li>
  <li>Element A3</li>
</ul>
Text that separates group A from group B
<ul>
  <li>Element B1</li>

  <li>Element B2</li> <li>Element B3</li>
  <li>Element B4</li>
</ul>
<strong>Element that separates group B from group C</strong>
<ul>
  <li>Element C1</li>
  <li>Element C2</li>
</ul>
Text can follow. 

I was thinking about using regex (I know, usually not the best idea for html). But here I don’t know how to recognize the ending </li> (or etc.) that is followed by anything other than a white space or another opening <li> (or < li > etc.)

I could also remove all white spaces between a > and a <; maybe the world would be a little bit easier then. But even then I don’t know how to “include” an opening LI as a valid following element within a group and exclude everything else.


Get this bounty!!!

#StackBounty: #php #mongodb #laravel #laravel-5 #jwt Multi Jwt Auth with Laravel and Mongodb

Bounty: 50

I have three types of Authenticatable model and I need to have separate JWT authentication for each. Let me explain more about my issue.

I’m using MongoDB as my database and Laravel MongoDB is the package that I use.

User, Admin, and ServiceProvider are my models.

To having JWT auth in Laravel I use jwt-auth package. It’s ok with user model (collection). when I want to use JWT with any of other models It not work and do everything with user again.

I search a lot an I found out that to change the provider user model I can use Config::set(); method like below,

Config::set('jwt.user', Admin::class);
Config::set('auth.providers.users.model', Admin::class);

But no effect on JWT auth. (I checked the value of 'jwt.user' and 'auth.providers.users.model' with Config::get() method and returned it, It has been changed to 'AppAdmin').

Need to say, My codes are as simple as possible according to the documentation of the package.
Here is my UserController code:

class UserController extends Controller
{
    public function login(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|string|email|max:255',
            'password' => 'required|min:6'
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors());
        }

        $credentials = $request->only('email', 'password');

        try {
            if (!$token = JWTAuth::attempt($credentials)) {
                return response()->json(['error' => 'invalid_credentials'], 401);
            }
        } catch (JWTException $e) {
            return response()->json(['error' => 'could_not_create_token'], 500);
        }

        $user = User::where('email', $request->email)->first();
        return response()->json([
            'user' => $user,
            'token' => $token
        ]);
    }

    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|string|email|max:255|unique:users',
            'phone' => 'required|valid_phone|unique:users',
            'password' => 'required|min:6',
            'first_name' => 'required',
            'last_name' => 'required',
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors());
        }

        User::create([
            'phone' => $request->get('phone'),
            'first_name' => $request->get('first_name'),
            'last_name' => $request->get('last_name'),
            'city_abbr' => $request->get('city_abbr'),
            'email' => $request->get('email'),
            'password' => bcrypt($request->get('password')),
        ]);
        $user = User::first();
        $token = JWTAuth::fromUser($user);

        return response()->json([
            'user' => $user,
            'token' => $token
        ]);

    }

}

And my AdminController:

class AdminController extends Controller
{

    public function login(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|string|email|max:255',
            'password' => 'required|min:6'
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors());
        }

        $credentials = $request->only('email', 'password');

        Config::set('jwt.user', Admin::class);
        Config::set('auth.providers.users.model', Admin::class);

        try {
            if (!$token = JWTAuth::attempt($credentials)) {
                return response()->json(['error' => 'invalid_credentials'], 401);
            }
        } catch (JWTException $e) {
            return response()->json(['error' => 'could_not_create_token'], 500);
        }

        $admin = Admin::where('email', $request->email)->first();
        return response()->json([
            'admin' => $admin,
            'token' => $token
        ]);
    }

    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|string|email|max:255|unique:admins',
            'phone' => 'required|valid_phone|unique:admins',
            'password' => 'required|min:6',
            'name' => 'required',
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors());
        }

        Admin::create([
            'phone' => $request->get('phone'),
            'name' => $request->get('name'),
            'access' => $request->get('access'),
            'email' => $request->get('email'),
            'password' => bcrypt($request->get('password')),
        ]);
        Config::set('jwt.user', Admin::class);
        Config::set('auth.providers.users.model', Admin::class);

        $admin = Admin::first();
        $token = JWTAuth::fromUser($admin);

        return response()->json([
            'admin' => $admin,
            'token' => $token
        ]);

    }

}

Am I wrong in somewhere?
Is there any solution for this?

Any solution will be appreciated.


Get this bounty!!!

#StackBounty: #php #laravel #eloquent How to get the name and price of the registration type(s) associated with a registration? (Eloque…

Bounty: 50

When the user clicks in a Pay button he is redirected to a payment page like “http://proj.test/conference/2/conference-title/payment/registration/6“, where 6 is the registration id that the user wants to pay and “2” is the conference id, so the user is paying a registration concerning the conference with id “2”.

In the registration payment page should appear a summary of the registration. For example, if a user did a registration in a conference with 3 tickets/registration types, 1 of the type “general” and 2 of the type “plus”, it should appear a summary like:

Title of the conference (ex: Conference test)
Date of the conference

Registration Type   Quantity         Price     Subtotal
 general             1            0.00 €      0.00$
 plus                2            1.00 €      2.00$

So I have this route for when the user clicks in the Pay button:

Route::get('/conference/{id}/{slug?}/payment/registration/{regID}', [
    'uses' => 'PaymentController@showSummary',
    'as'   =>'conferences.showSummary'
]);

In the showSummary() and I already get the conference name and date:

public function showSummary($id = "", $slug = "", $regID){

    $registration = Registration::with([
        'conference' => function ($query) {
            $query->select('id', 'name', 'date');
        }
    ])->find($regID);       
}

Doubt: My doubt is how to change the following query to get the name and the price of each registration type associated with the registration, and also get the quantity so is possible to show a summary like the summary above.

With:

$registrationTypeDetails = Registration::with([
            'participants' => function ($query) {
                $query->select('id', 'registration_type_id', 'registration_id')->where('registration_id', $regID);
            }
        ])->find($regID);

        dd($registrationTypeDetails);

The $registrationTypeDetails shows the participants associated with the registration:

Registration {#264 ▼
...
  #relations: array:1 [▼
    "participants" => Collection {#261 ▼
      #items: array:2 [▼
        0 => Participant {#269 ▼
          #fillable: array:4 [▶]
          ...
          #attributes: array:3 [▼
            "id" => 3
            "registration_type_id" => 2
            "registration_id" => 2
          ]
         ...
        }
        1 => Participant {#271 ▼
          #fillable: array:4 [▶]
          ....
          #attributes: array:3 [▼
            "id" => 4
            "registration_type_id" => 3
            "registration_id" => 2
          ]
         ....
        }
      ]
    }
  ]
}

So with the above query is possible to get to the registration_type_id of the participants associated to the registration and so should be possible to get the info about each registration type but I’m not understanding how to change the query to achieve that.

Do you know how to achieve that?


Relevant tables structure for the question:

Registration: id, status, conference_id, main_participant_id   
    (main_participant_id is the id of the user that did the regitration)

Registration Types: id, name, price, conference_id

Conference: id, name, date, organizer_id

Participant: id, registration_id, registration_type_id, name, surname

Relevant models for the question:

User model:

 class User extends Authenticatable
    {
        public function conferences(){
            return $this->hasMany('AppConference', 'organizer_id');
        }
        public function registrations(){
            return $this->hasMany('AppRegistration','main_participant_id');
        }
    }

Conference model:

class Conference extends Model
{
    public function organizer(){
        return $this->belongsTo('AppUser', 'organizer_id');
    }
    public function registrationTypes(){
        return $this->hasMany('AppRegistrationType', 'conference_id');
    }
    public function registrations(){
        return $this->hasMany('AppRegistration', 'conference_id');
    }
}

Registration Type model:

class RegistrationType extends Model
{
    public function conference(){
        return $this->belongsTo('AppConference');
    }

    // a registration can have many participants
    public function participants(){
       return $this->hasMany('AppParticipant');
    }
}

Registration model:

class Registration extends Model
{
    // a registration has one user that do the registration
    public function customer(){
        return $this->belongsTo(User::class, 'main_participant_id', 'id');
    }

    // a registration can have many participants
    public function participants(){
       return $this->hasMany('AppParticipant');
    }

    public function conference(){
        return $this->belongsTo('AppConference');
    }

    public function payment()
    {
        return $this->hasOne('AppPayment');
    }
}

Participant model:

class Participant extends Model
{

    // a participant belongs to a registration
    public function registration(){
        return $this->belongsTo('AppRegistration');
    }

    public function registration_type(){
        return $this->belongsTo('AppRegistrationType');
    }
}


Get this bounty!!!

#StackBounty: #javascript #php #jquery #ajax #cordova PhoneGap Allow (Ajax Request) Server side PHP files access just for this app (Sec…

Bounty: 50

I have created a android app using PhoneGap (PhoneGap is a tool which supports you to create apps using the web languages like HTML, CSS, and JavaScript.).

This is my function.


    $(document).ready(function() {
        $("#insert").click(function() {
            var title = $("#title").val();
            var duration = $("#duration").val();
            var price = $("#price").val();
            var dataString = "title=" + title + "&duration=" + duration + "&price=" + price + "&insert=";
            if ($.trim(title).length > 0 & $.trim(duration).length > 0 & $.trim(price).length > 0) {
                $.ajax({
                    type: "POST",
                    url: "http://www.example.com/test/insert.php",
                    data: dataString,
                    crossDomain: true,
                    cache: false,
                    beforeSend: function() {
                        $("#insert").val('Connecting...');
                    },
                    success: function(data) {
                        if (data == "success") {
                            alert("inserted");
                            $("#insert").val('submit');
                        } else if (data == "error") {
                            alert("error");
                        }
                    }
                });
            }
            return false;
        });
    });
    

This function should update the table which is on the server using http://www.example.com/test/insert.php. It works fine without any problems when the app is installed on a android phone.

But other users could easily update my table using above function. I mean if they know the URL (http://www.example.com/test/insert.php) they can also update my table passing necessary post requests.

How do I prevent this from happening? How could I allow accessing the page http://www.example.com/test/insert.php limited to just my app. I mean if request are coming from my app http://www.example.com/test/insert.php it should work.


Get this bounty!!!

#StackBounty: #php #rest #twitter #twitter-oauth PHP – Twitter API (OAuth) with pagination not working properly

Bounty: 50

I have integrated Twitter API (Twitter OAuth) to get latest feeds of particular company account and here below is my code what I have done so far (https://tomelliott.com/php/authenticating-twitter-feed-timeline-oauth).

<?php 
require_once("twitteroauth/twitteroauth.php"); //Path to twitteroauth library

$twitteruser = "CompanyName";
$notweets = 3;
$consumerkey = "xxxxxxxx";
$consumersecret = "xxxxxxxx";
$accesstoken = "xxxxxxxx";
$accesstokensecret = "xxxxxxxx";

function getConnectionWithAccessToken($cons_key, $cons_secret, $oauth_token, $oauth_token_secret)
{
    $connection = new TwitterOAuth($cons_key, $cons_secret, $oauth_token, $oauth_token_secret);
    return $connection;
}

$connection = getConnectionWithAccessToken($consumerkey, $consumersecret, $accesstoken, $accesstokensecret);

$tweets = $connection->get("https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=" . $twitteruser . "&count=" . $notweets);


?>


                                <?php foreach ($tweets as $current_tweet) { ?>
                                    
REGENCY CORPORATE

created_at; echo date("F d Y, H:i A", strtotime($date)); ?>

<?php $twitt_url = '#'; $twitter_target = ''; if (!empty($current_tweet->id)) { $twitt_url = 'https://twitter.com/' . $twitteruser . '/status/' . $current_tweet->id; $twitter_target = 'target="_blank"'; } ?> <a href="<?php echo $twitt_url; ?>" class="hovicon effect-5 news-icon" <?php echo $twitter_target; ?> > <i class="fa fa-twitter"></i> </a> </div> <p class="MontRegular themeFontGrey"> <?php echo $current_tweet->text; ?> </p> </div> <?php if (!empty($current_tweet->entities->media[0]->media_url)) { ?>
entities->media[0]->media_url; ?>" alt="Images" height="20%" width="20%" />
<?php } ?> <hr /> </div> <?php } ?>

This works well, I am getting 3 latest tweets. Now I want to add pagination into this, hence I followed documentation provided by Twitter (https://developer.twitter.com/en/docs/basics/cursoring.html), and below is my updated code with cursor for the same and I printed the array (response).

<?php 
require_once("twitteroauth/twitteroauth.php"); //Path to twitteroauth library

$twitteruser = "CompanyName";
$notweets = 3;
$cursor = -1;

$consumerkey = "xxxxxxxx";
$consumersecret = "xxxxxxxx";
$accesstoken = "xxxxxxxx";
$accesstokensecret = "xxxxxxxx";

function getConnectionWithAccessToken($cons_key, $cons_secret, $oauth_token, $oauth_token_secret)
{
    $connection = new TwitterOAuth($cons_key, $cons_secret, $oauth_token, $oauth_token_secret);
    return $connection;
}

$connection = getConnectionWithAccessToken($consumerkey, $consumersecret, $accesstoken, $accesstokensecret);

$tweets = $connection->get("https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=" . $twitteruser . "&count=" . $notweets . "&cursor=" . $cursor);
echo '<pre>';
print_r($tweets);
exit;
?>

As you can see, here I have added $cursor = -1; and updated my api target url to $tweets = $connection->get("https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=" . $twitteruser . "&count=" . $notweets . "&cursor=" . $cursor);, passing cursor value.

Here I am getting the 3 recent tweets, however, as per mentioned in documentation from above link (https://developer.twitter.com/en/docs/basics/cursoring.html), you should get response like below.

{
    "ids": [
        385752029,
        602890434,
        ...
        333181469,
        333165023
    ],
    "next_cursor": 1374004777531007833,
    "next_cursor_str": "1374004777531007833",
    "previous_cursor": 0,
    "previous_cursor_str": "0"
}

I have also tried to update requested feed url to this.

$tweets = $connection->get("https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=" . $twitteruser .  "&cursor=" . $cursor);

But I am not getting any keys like next_cursor in any ways so far to be able to proceed. Can someone guide me, what I am doing wrong here, and what should I do to enable pagination from here on?

Any help or suggestion will be highly appreciated.

Thanks


Get this bounty!!!

#StackBounty: #php #css #mysql #bootstrap-4 #navbar Build boostrap4 navmenu from multiple mysql tables

Bounty: 50

I want to make a bootstrap 4 nav-menu, I have the following SQL query and I have some codes below it but I can’t get my head around how to do this!

These are the tables

TABLE menu
--------------------------------------
| id | title       | url             |
| 1  | Home        | index.php       |
| 2  | Menu        | #               |
| 3  | Contact     | #               |
| 2  | Winkelwagen | winkelwagen.php |
--------------------------------------

TABLE categories
-------------------------------------
| id | title_cat | url | cparent_id |
| 1  | Auto's    | #   | 2          |
| 2  | Drank     | #   | 2          |
-------------------------------------

TABLE products
-------------------------------------
| id | product  | url  | pparent_id |
| 1  | Ferrari  | #    | 1          |
| 2  | Heineken | #    | 2          |
-------------------------------------

Here is the query:

$query =    "SELECT
            X.level,
            X.id,
            X.name,
            X.url,
            X.parent_id
        FROM
            (
            SELECT
                1 AS LEVEL,
                id AS id,
                title AS NAME,
                url AS url,
                0 AS parent_id,
                id AS id_1,
                -1 AS id_2,
                -1 AS id_3
            FROM
                menu
            WHERE
                1
            UNION
        SELECT
            2 AS LEVEL,
            id AS id,
            title_cat AS NAME,
            url AS url,
            cparent_id AS parent_id,
            cparent_id AS id_1,
            id AS id_2,
            -1 AS id_3
        FROM
            categories
        WHERE
            1
        UNION
        SELECT
            3 AS LEVEL,
            products.id AS id,
            products.product AS NAME,
            products.url AS url,
            products.pparent_id AS parent_id,
            categories.cparent_id AS id_1,
            categories.id AS id_2,
            products.id AS id_3
        FROM
            products
        LEFT JOIN categories ON products.pparent_id = categories.id
        WHERE
            1
        ) X
        WHERE
            1
        ORDER BY
            id_1,
            id_2,
            id_3";

Which gives the following table with levels (and I added the parent_id too, but with the parent_id buildTree($array) goes into a loop):

level   id  name        url             parent_id   
1       1   Home        index.php       0   
1       2   Menu        #               0   
2       1   Auto's      #               2   
3       1   Ferrari     #               1   
2       2   Drank       #               2   
3       2   Heineken    #               2   
1       3   Contact     contact.php     0   
1       4   Winkelwagen winkelwagen.php 0   

I want the nav-menu to look like this:

        <li class="nav-item">
            <a class="nav-link" href="index.php">Home</a>
        </li>
        <li class="nav-item dropdown">
            <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Menu</a>
            

I have the following codes, first we make a array from the query fetched which you already saw above:

$sql = $pdo->prepare($query);

function menu_builder($sql) {
    if ($sql->execute()) {
        while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {
            $array[] = $row;
        }
        buildTree($array); // or menu_builder($sql);
    }
}

The next code doesn’t work because it goes into a infinite loop (and if it works I still need to make the html right :):

function buildTree($array, $parent_id = 0, $parents = array()) {
    if($parent_id == 0) {
        foreach ($array as $element) {
            if (($element['parent_id'] != 0) && !in_array($element['parent_id'], $parents)) {
                $parents[] = $element['parent_id'];
            }
        }
    }
    $menu_html = '';
    foreach($array as $element) {
        if($element['parent_id'] == $parent_id) {
            if(in_array($element['id'], $parents)) {
                $menu_html .= '<li class="dropdown">';
                $menu_html .= '<a href="'.$element['url'].'" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">'.$element['name'].' <span class="caret"></span></a>';
            }
            else {
                $menu_html .= '<li>';
                $menu_html .= '<a href="' . $element['url'] . '">' . $element['name'] . '</a>';
            }
            if(in_array($element['id'], $parents)) {
                $menu_html .= '<ul class="dropdown-menu" role="menu">';
                $menu_html .= buildTree($array, $element['id'], $parents);
                $menu_html .= '</ul>';
            }
            $menu_html .= '</li>';
        }
    }
    return $menu_html;
}

And this one makes a normal <ul>/<li> menu which I don’t know how to get it working for me with bootstrap:

function menu_builder($sql) {
    $level = 0;
    if ($sql->execute()) {
        while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {
            while($level < $row['level']) {
                echo "<ul>" . PHP_EOL;
                $level++;
            }
            while($level > $row['level']) {
                echo "</ul>" . PHP_EOL;
                $level--;
            }
            echo "    <li>#" . $row['id'] . "->" . $row['name'] . "</li>" . PHP_EOL;
        }
    }
    while($level-- > 0) {
       echo "</ul>" . PHP_EOL;
    }
}

If you need more information please ask me, I tried to make the question as clear as possible with the codes I’m trying and the table I’m using.

jQuery:

$('.dropdown-menu a.dropdown-toggle').on('click', function(e) {
    if (!$(this).next().hasClass('show')) {
        $(this).parents('.dropdown-menu').first().find('.show').removeClass("show");
    }
    var $subMenu = $(this).next(".dropdown-menu");
    $subMenu.toggleClass('show');
    $(this).parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', function(e) {
        $('.dropdown-submenu .show').removeClass("show");
    });
    return false;
});

CSS:

.dropdown-submenu {
  position: relative;
}

.dropdown-submenu a::after {
  transform: rotate(-90deg);
  position: absolute;
  right: 6px;
  top: .8em;
}

.dropdown-submenu .dropdown-menu {
  top: 0;
  left: 100%;
  margin-left: .1rem;
  margin-right: .1rem;
}


Get this bounty!!!

#StackBounty: #linux #ubuntu #permissions #php #nginx Nextcloud: Can’t create or write into the data directory /var/nc_data

Bounty: 50

I’m getting the above error. What I tried so far:

  • checked the permissions. I even did chmod 777 /var/nc_data -R
  • first included all used party in open_basedir in my php.ini. When that didn’t work, I commented it out completely (in fpm and cli php.ini)
  • checked if SELinux is active. It isn’t.

I don’t have any more ideas to start with. I run an ubuntu server 18.04 inside a Hyper-V virtual machine. I use nginx 1.14.0, mariadb 10.1.29, php 7.2 and nextcloud 13.0.2.

Does someone have an idea?

Or could tell me where more error details could be logged so I have something to start with. nginx and php logs just have notices in them.

Thank you guys in advance 🙂

Marin

PS: Nextcloud vHost configuration: https://pastebin.com/wZJLp0rx

PPS: Nextcloud config.php:

<?php
$CONFIG = array (
  'instanceid' => 'oc2xpzs4xkog',
);

(it’s not much written in because it’s not set up yet)


Get this bounty!!!

#StackBounty: #php #laravel #guzzle Getting the value of a cookie from an HTTP call using GuzzleHttp

Bounty: 50

I am now using GuzzleHttp to make HTTP requests, first I make a POST request to login.asp, which returns a response with Set-Cookie with a value that I need for future requests

enter image description here

When I inspect my obtained answer I get the following

enter image description here

As noted, I get all the keys except the Set-Cookie, what can be happening? How can I get this value? I’m using "guzzlehttp/guzzle": "^6.3", or can I get it using another tool?

    $jar = new CookieJar;

    $client = new Client([
        'base_uri' =>'miurl/',
        'timeout'  => 10.0,
        'cookies' => $jar
    ]);

    $response = $client->request('POST', 'login.asp',  [
        'form_params' => [
            'pws' => '',//data password
            'user' => '',//data user
        ]
    ]);

    //Request require coookies

    $response = $client->request('POST', 'goform/Wls',  [
        'form_params' => [
            /*Form´Params*/
        ],
       //if I manually add a correct userid the post application works fine
        'headers' => [
            //Require cookie param userid 
            'Cookie' => 'LANG_COOKIE=lang_span; userid=1524324306',
        ]
    ]);

Alternatively, I used this configuration without being able to obtain the cookie yet

checking a bit the answer using postman, is that after doing the correct login is still on the same page but with javascript redirect, can this influence?

window.location='/admin/cable-Systeminfo.asp';
</html>

The requests I make directly for a router hitron technologies cgnv22 to manage the mac filtering, I would like to provide more information but it is sensitive information


Get this bounty!!!

#StackBounty: #php #database #laravel #database-design The database is correctly structured to handled the scenario when "all_part…

Bounty: 50

I have a context where I have a form for a user do a registration in a congress. And there are two different scenarios, if “all_participant” is “1” in the congress table is necessary to collect the name and surname about each participant that the user is registering, if “all_participant” is “0” is only necessary to use the info (name, surname, auth id) of the auth user (the user that is doing the registration) for the registration.

When “all_participant” is “1” it works like:
For example if the user “John” selected 2 tickets, one ticket of the ticket type “tt1” and other of the ticket type “tt2” and “all_participants” is 1 which means that he needs to enter the name and surname of each participant to associate each participant to a ticket type. So it will appear two name and surname fields in the registration form. And the John enter in one name field his name and in one surname field his surname and in the other name field the name of his collueague Jake and in the other surname field the surname of his collueague Jake.

Then, each ticket type can have 1 or more custom question(s) associated, for example, the ticket type “tt1″ can have the custom question Whats your phone?” associated and the ticket type “ticket type 2” dont have any custom question associated. So it will appear only one field “Whats your phone?” in the registration form, because only the ticket type “tt1” has 1 custom question associated.

When the user click “Go to step 2” in the registration form, is inserted an entry in the Registrations table, an entry for each participant in Participants table and entries in the answers table relative to the answers to the custom questions. So the database stays like below when the user click in “Go to step 2” in the registration form:

Registrations table: 
id       status        congress_id        main_participant_id
7          C              1                         1   
Participants table:
id   registration_id      ticket_type_id        name        surname
12        7                     1                  John         W
13        7                     2                   Jake        Y
Answers table:
id    participant_id     question_id      answer
2           12              1               0002
3            13             1               0003

When “all_participant” is “0” it works like: (DOUBT)

My doubt is about how to store the information when “all_participants” is “0”. So the user John that is doing the registration selected 2 tickets, one ticket of the ticket type “tt1” and other of the ticket type “tt2”, and the ticket type “tt1” has 1 custom question associated and now “all_participants” is “0”, which means that is not necessary to collect info about each participant, is only necessary to use the info of the auth user to do the registration.

But if there are custom questions is necessary that the auth user (the user that is doing the registration) answer these custom questions, but if “all_participant” is “0” only the user that is doing the registration needs to answer these questions, so for example if the user selected two tickets and 1 or more have some custom questions associated, in the registration form, besides the user selected 2 tickets in the registration form it will only appear once the custom question(s) and not twice because is only for the user that is doing the registration to answer. So in this scenario when user clicks in the “Go to step 2” in the registration form the database stays like:

Registrations table:
id       status        congress_id        main_participant_id
10         C                1                   1   

Participants table: (name and surname and blank because when "all_participant" is "0" is not necessary to collect name and surname of each participant)
id   registration_id      ticket_type_id        name        surname
18        10                     1                          
19        10                     2                   
Answers table:
id    participant_id     question_id      answer
4           18              1               0002

Doubt:

My doubt is if you know if this is structured correctly because as it is it seems that is not possible to know to which user the answers belong
when “all_participant” is “0” and there are custom questions in 1 or more ticket types selected by the user. Because the ansers table only have the participant_id which in this case is “18” but the user that did the registration is the user in the users table with id “1”.

The main_participant_id in the registrations table is the id of the user in the users table that did the registration which allow to know which user did the registration.

Relationships relevant for the question:

1 to many between Congresses and Registrations
1 to many between Congresses and TicketTypes
1 to many between Registrations and Participants
1 to many between TicketTypes and Participants
1 to many between Participants and Answers
1 to many between Questions and Answers
Many to Many between TicketTypes and Questions
1 to many between Congresses and Questions


Get this bounty!!!