Does anyone know where the source code is located for the built in Laravel 5 helper functions like view() and str_limit()? I am curious to see how they are doing things in the background.
view function is located under
/vendor/laravel/framework/source/illuminate/Foundation/helpers.php
line number 585
content is as follows:
if ( ! function_exists('view'))
{
/**
* Get the evaluated view contents for the given view.
*
* #param string $view
* #param array $data
* #param array $mergeData
* #return \Illuminate\View\View
*/
function view($view = null, $data = array(), $mergeData = array())
{
$factory = app('Illuminate\Contracts\View\Factory');
if (func_num_args() === 0)
{
return $factory;
}
return $factory->make($view, $data, $mergeData);
}
}
start using an IDE like Php storm and you can find all this functions with a single click
Related
Normally TYPO3 assigns a variable in FrontEnd with the name validationResults and it looks like that.
Then we have to iterate through the Error objects and get a list with all the errors and their messages. But there is no way to take each one individually and assign it on the corresponding field where the error appears.
So the question is, how do i do it?
Best regards,
After some programming and a help from larry-pete (typo3.slack.com) i found a solution.
I created my own ViewHelper and it looks like this:
ext_localconf.php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['namespaces']['mytag'][] = 'Vendor\\ExtensionName\\ViewHelpers';
Classes/ViewHelpers/Form/ErrorViewHelper.php
namespace Vendor\ExtensionName\ViewHelpers\Form;
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormFieldViewHelper;
class ErrorViewHelper extends AbstractFormFieldViewHelper
{
use CompileWithRenderStatic;
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* #var bool
*/
protected $escapeOutput = false;
public function initializeArguments()
{
$this->registerArgument('for', 'string', 'The name of the error name (e.g. argument name or property name). This can also be a property path (like blog.title), and will then only display the validation errors of that property.', false, '');
$this->registerArgument('as', 'string', '', false, 'flattenedErrors');
}
/**
* #param array $arguments
* #param \Closure $renderChildrenClosure
* #param RenderingContextInterface $renderingContext
* #return mixed
*/
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
$as = $arguments['as'];
$for = $arguments['for'];
$templateVariableContainer = $renderingContext->getVariableProvider();
$controllerContext = $renderingContext->getcontrollerContext();
$validationResults = $controllerContext->getRequest()->getOriginalRequestMappingResults();
if ($validationResults !== null){
$validationResults = $validationResults->forProperty($for);
}
$flattenedErrors = $validationResults->getErrors();
$output = $renderChildrenClosure();
$withKeys = [];
if (empty($output)) {
if ($flattenedErrors) {
foreach ($flattenedErrors as $error) {
$withKeys[$error->getTitle()] = $error;
}
}
}
$templateVariableContainer->add($as, $withKeys);
return $output;
}
}
Form.html
<mytag:form.error as="error" for="error"/>
And this returns:
So now, you can do something like that:
<f:if condition="{offer.firstName}"><span style="display: block">{offer.firstName.message}</span></f:if>
Best regards
I changed your Viewhelper a bit because it didn't worked in my version (typo3 9)
<?php
namespace Vendor\Extension\ViewHelpers;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
class ErrorViewHelper extends AbstractViewHelper
{
use CompileWithRenderStatic;
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* #var bool
*/
protected $escapeOutput = false;
public function initializeArguments()
{
$this->registerArgument('for', 'string', 'The name of the error name (e.g. argument name or property name). This can also be a property path (like blog.title), and will then only display the validation errors of that property.', false, '');
}
/**
* #param array $arguments
* #param \Closure $renderChildrenClosure
* #param RenderingContextInterface $renderingContext
* #return mixed
*/
public static function renderStatic(
array $arguments,
\Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext
) {
$for = $arguments['for'];
$controllerContext = $renderingContext->getControllerContext();
$validationResults = $controllerContext->getRequest()->getOriginalRequestMappingResults();
if ($validationResults !== null) {
$validationResults = $validationResults->forProperty($for);
}
$flattenedErrors = $validationResults->getFlattenedErrors();
return $flattenedErrors;
}
}
you can do:
{myExt:error() -> f:variable(name: 'errors')}}
or
{ff:error( for:"user" ) -> f:variable(name: 'errors')}}
What is the simple way to share partials between themes. Assets are possible but i am having issue with whole partials. I have a multi-theme site managed/activated by sub-domain policies/logic.
SOLUTIONS
/**
*
* Renders a requested partial in context of this component,
* see Cms\Classes\Controller#renderPartial for usage.
*/
/**
* #param $themeName
* #param $partialName
* #param $data
* #return mixed
* #throws \Cms\Classes\CmsException
*/
public function renderThemePartial($partialName, $themeName, $data)
{
$theme = Theme::getActiveTheme();
if($themeName) {
$theme = Theme::load($themeName);
}
$controller = new Controller($theme);
return $controller->renderPartial($partialName, $data);
}
/**
*
* Renders a requested content in context of this component,
* see Cms\Classes\Controller#renderContent for usage.
*/
/**
* #param $themeName
* #param $contentName
* #param $data
* #return string
* #throws \Cms\Classes\CmsException
*/
public function renderThemeContent($contentName, $themeName, $data)
{
$theme = Theme::getActiveTheme();
if($themeName) {
$theme = Theme::load($themeName);
}
$controller = new Controller($theme);
return $controller->renderContent($contentName, $data);
}
public function registerMarkupTags()
{
return [
'functions' => [
'partial_from_theme' => [$this, 'themePartial'],
'content_from_theme' => [$this, 'themeContent'],
],
'filters' => [
'theme_asset' => [$this, 'themeUrl']
]
];
}
/**
* #param $requested
* #return string
*/
public function themeUrl($requested)
{
$asset = $requested[0];
$theme = $requested[1];
$theme = Theme::load($theme);
$themeDir = $theme->getDirName();
if (is_array($asset)) {
$_url = Url::to(CombineAssets::combine($asset, themes_path().'/'.$themeDir));
}
else {
$_url = Config::get('cms.themesPath', '/themes').'/'.$themeDir;
if ($asset !== null) {
$_url .= '/'.$asset;
}
$_url = Url::asset($_url);
}
return $_url;
}
/**
* #param $partialName
* #param null $themeName
* #param array $parameters
* #return mixed
* #throws \Cms\Classes\CmsException
*/
public function themePartial($partialName, $themeName = null, $parameters = [])
{
return $this->renderThemePartial($partialName, $themeName, $parameters);
}
/**
* #param $contentName
* #param null $themeName
* #param array $parameters
* #return string
* #throws \Cms\Classes\CmsException
*/
public function themeContent($contentName, $themeName = null, $parameters = [])
{
return $this->renderThemeContent($contentName, $themeName, $parameters);
}
I guess you can use Plugin component here you can add component to page and use its partial.
You need to define partial [ you can add as many as you like ] in component.
And just use that partial like below in page , now this same thing you can do in other themes as well.
When you change partial it will affect in all other themes like its shared across multiple themes.
Down side will be that you can not change its content from backend, you need to manually change that file from ftp or other manner.
Partial from another theme
Hmm
you can add custom twig function for that may be
In any of your plugin you can add this code
public function registerMarkupTags()
{
return [
'functions' => [
'theme_partial' => [$this, 'themePartial'],
]
];
}
public function themePartial($partialName, $themeName = null, $vars = [])
{
$theme = Theme::getActiveTheme();
if($themeName) {
$theme = Theme::load($themeName);
}
$template = call_user_func([Partial::class, 'load'], $theme, $partialName);
$partialContent = $template->getTwigContent();
$html = Twig::parse($partialContent, $vars);
return $html;
}
Now inside your theme when you want to use partial you can use
{{ theme_partial('call_from_other_theme', 'stemalo' ,{'name':'hardik'}) }}
^ Your theme name here.
themes/stemalo/partials/call_from_other_theme.htm content
description = "Shared Partial."
[viewBag]
==
<div id="shared_partial">
<h1>Another Theme Partial : {{name}}</h1>
</div>
this way you can use partial from another themes.
you aksed for access to theme directory here may be you can just you need to pass theme name, and `its dynamic you can pass variable as theme name so it can pick any thing you like.
If any doubt please comment.
I know the question was already ask but i have tried without success.
We have an old database with SHA256 and double salt and we wan't to use this for Register and Login.
I have follow this tutorial and many more : https://conceptsandimplementation.wordpress.com/2017/03/07/replace-laravels-default-password-hash-bcrypt-with-base64-encode/
This my code :
namespace App\Libs\CustomHash;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
class CustomHasher implements HasherContract {
public function info($hashedValue) {
}
/**
* Hash the given value.
*
* #param string $value
* #return array $options
* #return string
*/
public function make($value, array $options = array()) {
$PasswordHashed = 'a5df5z' . $value . 'a45ee1a';
$PasswordHashed = hash('sha256', $value);
return $PasswordHashed;
}
/**
* Check the given plain value against a hash.
*
* #param string $value
* #param string $hashedValue
* #param array $options
* #return bool
*/
public function check($value, $hashedValue, array $options = array()) {
return $this->make($value) === $hashedValue;
}
/**
* Check if the given hash has been hashed using the given options.
*
* #param string $hashedValue
* #param array $options
* #return bool
*/
public function needsRehash($hashedValue, array $options = array()) {
return false;
}
}
And :
namespace App\Providers;
use Illuminate\Hashing\HashServiceProvider;
use App\Libs\CustomHash\CustomHasher as CustomHasher;
class CustomHashServiceProvider extends HashServiceProvider
{
public function register()
{
$this->app->singleton('hash', function () {
return new CustomHasher;
});
}
}
Here my providers list
//Illuminate\Hashing\HashServiceProvider::class,
App\Providers\CustomHashServiceProvider::class,
I know that's not a good practive to use SHA but i do not have the choice.
Thank's in advance for you're help.
I've configured Laravel Scout and can use ::search() on my models.
The same models also use SoftDeletes. How can I combine the ::search() with withTrashed()?
The code below does not work.
MyModel::search($request->input('search'))->withTrashed()->paginate(10);
The below does work but does not include the trashed items.
MyModel::search($request->input('search'))->paginate(10);
Update 1
I found in the scout/ModelObserver that deleted items are made unsearchable. Which is a bummer; I wanted my users to be able to search through their trash.
Update 2
I tried using ::withoutSyncingToSearch, as suggested by #camelCase, which I had high hopes for, but this also didn't work.
$model = MyModel::withTrashed()->where('slug', $slug)->firstOrFail();
if ($model->deleted_at) {
$model->forceDelete();
} else {
MyModel::withoutSyncingToSearch(function () use ($model) {
$model->delete();
});
}
This caused an undefined offset when searching for a deleted item. By the way, I'm using the TNTSearch driver for Laravel Scout. I don't know if this is an error with TNTSearch or with Laravel Scout.
I've worked out a solution to your issue. I'll be submitting a pull request for Scout to hopefully get it merged with the official package.
This approach allows you to include soft deleted models in your search:
App\User::search('search query string')->withTrashed()->get();
To only show soft deleted models in your search:
App\User::search('search query string')->onlyTrashed()->get();
You need to modify 3 files:
Builder.php
In laravel\scout\src\Builder.php add the following:
/**
* Whether the search should include soft deleted models.
*
* #var boolean
*/
public $withTrashed = false;
/**
* Whether the search should only include soft deleted models.
*
* #var boolean
*/
public $onlyTrashed = false;
/**
* Specify the search should include soft deletes
*
* #return $this
*/
public function withTrashed()
{
$this->withTrashed = true;
return $this;
}
/**
* Specify the search should only include soft deletes
*
* #return $this
*/
public function onlyTrashed()
{
$this->onlyTrashed = true;
return $this;
}
/**
* Paginate the given query into a simple paginator.
*
* #param int $perPage
* #param string $pageName
* #param int|null $page
* #return \Illuminate\Contracts\Pagination\LengthAwarePaginator
*/
public function paginate($perPage = null, $pageName = 'page', $page = null)
{
$engine = $this->engine();
$page = $page ?: Paginator::resolveCurrentPage($pageName);
$perPage = $perPage ?: $this->model->getPerPage();
$results = Collection::make($engine->map(
$rawResults = $engine->paginate($this, $perPage, $page), $this->model, $this->withTrashed, $this->onlyTrashed
)); // $this->withTrashed, $this->onlyTrashed is new
$paginator = (new LengthAwarePaginator($results, $engine->getTotalCount($rawResults), $perPage, $page, [
'path' => Paginator::resolveCurrentPath(),
'pageName' => $pageName,
]));
return $paginator->appends('query', $this->query);
}
Engine.php
In laravel\scout\src\Engines\Engine.php modify the following:
/**
* Map the given results to instances of the given model.
*
* #param mixed $results
* #param \Illuminate\Database\Eloquent\Model $model
* #param boolean $withTrashed // New
* #return \Illuminate\Database\Eloquent\Collection
*/
abstract public function map($results, $model, $withTrashed, $onlyTrashed); // $withTrashed, $onlyTrashed is new
/**
* Get the results of the given query mapped onto models.
*
* #param \Laravel\Scout\Builder $builder
* #return \Illuminate\Database\Eloquent\Collection
*/
public function get(Builder $builder)
{
return Collection::make($this->map(
$this->search($builder), $builder->model, $builder->withTrashed, $builder->onlyTrashed // $builder->withTrashed, $builder->onlyTrashed is new
));
}
And finally, you just need to modify your relative search engine. I'm using Algolia, but the map method appears to be the same for TNTSearch.
AlgoliaEngine.php
In laravel\scout\src\Engines\AlgoliaEngine.php modify the map method to match the abstract class we modified above:
/**
* Map the given results to instances of the given model.
*
* #param mixed $results
* #param \Illuminate\Database\Eloquent\Model $model
* #param boolean $withTrashed // New
* #return \Illuminate\Database\Eloquent\Collection
*/
public function map($results, $model, $withTrashed, $onlyTrashed) // $withTrashed, $onlyTrashed is new
{
if (count($results['hits']) === 0) {
return Collection::make();
}
$keys = collect($results['hits'])
->pluck('objectID')->values()->all();
$modelQuery = $model->whereIn(
$model->getQualifiedKeyName(), $keys
);
if ($withTrashed) $modelQuery->withTrashed(); // This is where the query will include deleted items, if specified
if ($onlyTrashed) $modelQuery->onlyTrashed(); // This is where the query will only include deleted items, if specified
$models = $modelQuery->get()->keyBy($model->getKeyName());
return Collection::make($results['hits'])->map(function ($hit) use ($model, $models) {
$key = $hit['objectID'];
if (isset($models[$key])) {
return $models[$key];
}
})->filter();
}
TNTSearchEngine.php
/**
* Map the given results to instances of the given model.
*
* #param mixed $results
* #param \Illuminate\Database\Eloquent\Model $model
*
* #return Collection
*/
public function map($results, $model, $withTrashed, $onlyTrashed)
{
if (count($results['ids']) === 0) {
return Collection::make();
}
$keys = collect($results['ids'])->values()->all();
$model_query = $model->whereIn(
$model->getQualifiedKeyName(), $keys
);
if ($withTrashed) $model_query->withTrashed();
if ($onlyTrashed) $model_query->onlyTrashed();
$models = $model_query->get()->keyBy($model->getKeyName());
return collect($results['ids'])->map(function ($hit) use ($models) {
if (isset($models[$hit])) {
return $models[$hit];
}
})->filter();
}
Let me know how it works.
NOTE: This approach still requires you to manually pause syncing using the withoutSyncingToSearch method while deleting a model; otherwise the search criteria will be updated with unsearchable().
this is my solution.
// will return matched ids of my model instance
$searchResultIds = MyModel::search($request->input('search'))->raw()['ids'];
MyModel::whereId('id', $searchResultIds)->onlyTrashed()->get();
I am trying to develop a joomla 1.6 component. I am getting the following error
Fatal error: Call to a member function getKeyName() on a non-object in
D:\xampp\htdocs\lab\libraries\joomla\application\component\modeladmin.php
on line 327
my model code is below
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla modelform library
jimport('joomla.application.component.modeladmin');
/**
* HelloWorld Model
*/
class CrudModelHiWorld extends JModelAdmin
{
/**
* Returns a reference to the a Table object, always creating it.
*
* #param type The table type to instantiate
* #param string A prefix for the table class name. Optional.
* #param array Configuration array for model. Optional.
* #return JTable A database object
* #since 1.6
*/
public function getTable($type = 'Crud', $prefix = 'CrudTable', $config = array())
{
return JTable::getInstance($type, $prefix, $config);
}
/**
* Method to get the record form.
*
* #param array $data Data for the form.
* #param boolean $loadData True if the form is to load its own data (default case), false if not.
* #return mixed A JForm object on success, false on failure
* #since 1.6
*/
public function getForm($data = array(), $loadData = true)
{
// Get the form.
$form = $this->loadForm('com_crud.hiworld', 'hiworlds', array('control' => 'jform', 'load_data' => $loadData));
if (empty($form))
{
return false;
}
return $form;
}
/**
* Method to get the data that should be injected in the form.
*
* #return mixed The data for the form.
* #since 1.6
*/
protected function loadFormData()
{
// Check the session for previously entered form data.
$data = JFactory::getApplication()->getUserState('com_crud.edit.hiworld.data', array());
if (empty($data))
{
$data = $this->getItem();
}
return $data;
}
}
Thanks