Huzaib Shafi Huzaib Shafi - 4 months ago 25
PHP Question

Let users create custom blade layouts / store in database

Problem: I need to let my web-app users create their own blade layout templates. So the most convenient solution is to store the blade templates into the database. However, I see no method to

extend
a child
view
from a layout code
NOT SPECIFIED
in a
blade file
.
Furthermore the next concern is security. I can't rely on users to insert
safe code
. Giving access to insert
php
code or directly
blade
code is disastrous for the system.
So how to?


  1. Save the layout template in database

  2. Make sure no part of the code gets executed on the server side.



As a side note, I can let users mention pre-specified tokens in the code, that shall be replaced by the results from the system.

Answer

Solution 1: Let users fill the database column (after filtering the given code for any possible php codes) and save it into a 'master' file, from which the final view is being extended. User may use given codes for content replacement

//master.blade.php
<html>
<head>
<%token%>
</head>
<body>
<%content%>
...
<%scripts%>
</body>
</html>

In the above code, the <% content %>

should be replaced by

@yield('content')

before the actual view is processed.

//final.blade.php
@extends('layouts.master')
@section('content')
...
@endsection

So the controller, saves the database column content into master.blade.php and then calls the view('final') function as necessary.

//In Controller
//Save the contents of database column in master.blade.php
return view('final',$data);

But this is NOT a GOOD solution. File write operation for every request, cache problems, security issues (such as service side execution script injection) etc. An alternate to this is having a master for each user, created only when the user makes changes in the template column. Thus benefiting from lesser file write operations, but file overload on the server because a file for every user in the file-system.


Solution 2: Save the user's layout code into database column (no filtering necessary).

//In controller
$content = View::make('final',compact('data'));
$token = "<meta name='_token' content='" . csrf_token() ."'";
$scripts = View::make('final_scripts',compact('data'));

$view = str_replace_first("<%content%>", $content, $templateInDatabase);
$view = str_replace_first("<%token%>", $token, $view);
$view = str_replace_first("<%scripts%>", $scripts, $view);

return $view;

The user shall be made to include the three <%X%> tags in the template code. Benefits are no server side code execution, hence added security. Cache problems minimize as the final & final_scripts blade templates can be cached. But the string replacements add extra effort.

Comments