An alternative to deprecated addKey() method in Magento? - magento

I am trying to add an index for a column over Magento data setup script.
/** #var Mage_Eav_Model_Entity_Setup $installer */
$installer = $this;
$installer->startSetup();
$installer
->getConnection()
->addKey(
$installer->getTable('enterprise_rma/rma'),
'IDX_EXPORT_DATE',
'export_date'
);
However our inspection tool complains:
The method Varien_Db_Adapter_Pdo_Mysql::addKey() has been deprecated with message: since 1.5.0.0
What I can use instead of addKey() in this case?

Look at the addKey function in the class Varien_Db_Adapter_Pdo_Mysql:
public function addKey($tableName, $indexName, $fields, $indexType = 'index', $schemaName = null)
{
return $this->addIndex($tableName, $indexName, $fields, $indexType, $schemaName);
}
It is just making a call to the addIndex function of the same class, this function is not deprecated, so you should use this one.
/**
* Add new index to table name
*
* #param string $tableName
* #param string $indexName
* #param string|array $fields the table column name or array of ones
* #param string $indexType the index type
* #param string $schemaName
* #return Zend_Db_Statement_Interface
* #throws Zend_Db_Exception|Exception
*/
public function addIndex($tableName, $indexName, $fields,
$indexType = Varien_Db_Adapter_Interface::INDEX_TYPE_INDEX, $schemaName = null)
(My code come from Magento Enterprise 1.12)

Related

Laravel Nova: TypeError: Cannot read property 'status' of undefined

A bunch of my Nova ressources stopped working. When trying to create them, I get the following error in the console:
Uncaught (in promise) TypeError: Cannot read property 'status' of undefined
at a.<anonymous> (app.js?id=7319bf5027431449796c:1)
at y (app.js?id=7319bf5027431449796c:1)
at Generator._invoke (app.js?id=7319bf5027431449796c:1)
at Generator.e.(anonymous function) [as next] (http://url/vendor/nova/app.js?id=7319bf5027431449796c:1:460720)
at o (app.js?id=7319bf5027431449796c:1)
at app.js?id=7319bf5027431449796c:1
at new Promise (<anonymous>)
at new t (app.js?id=7319bf5027431449796c:1)
at a.<anonymous> (app.js?id=7319bf5027431449796c:1)
at a.<anonymous> (app.js?id=7319bf5027431449796c:1)
Nothing shows up in the error log at all. Any pointers to where I should be looking? Only affects some ressources, others are working fine.
Edit: Here is one of the affected Nova ressources:
<?php
namespace App\Nova;
use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Fields\HasMany;
use Laravel\Nova\Fields\ID;
use Illuminate\Http\Request;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Http\Requests\NovaRequest;
use Naxon\NovaFieldSortable\Concerns\SortsIndexEntries;
use Naxon\NovaFieldSortable\Sortable;
class Unterprodukt extends Resource
{
use SortsIndexEntries;
public static $defaultSortField = 'order';
/**
* The model the resource corresponds to.
*
* #var string
*/
public static $model = 'App\Unterprodukt';
/**
* Get the displayble label of the resource.
*
* #return string
*/
public static function label()
{
return 'Unterprodukte';
}
/**
* Get the displayble singular label of the resource.
*
* #return string
*/
public static function singularLabel()
{
return 'Unterprodukt';
}
/**
* The logical group associated with the resource.
*
* #var string
*/
public static $group = 'Versicherung';
/**
* The single value that should be used to represent the resource when being displayed.
*
* #var string
*/
public static $title = 'name';
/**
* The columns that should be searched.
*
* #var array
*/
public static $search = [
'id',
'name',
];
/**
* Get the fields displayed by the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function fields(Request $request)
{
return [
ID::make()
->sortable()
->hideFromIndex(),
Text::make('Name', 'name')
->sortable(),
BelongsTo::make('Produkt', 'produkt', 'App\Nova\Produkt')
->sortable(),
Sortable::make('Reihenfolge', 'id')
->sortable(),
HasMany::make('Dokumente', 'dokumente', 'App\Nova\Dokument'),
];
}
/**
* Get the cards available for the request.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function cards(Request $request)
{
return [];
}
/**
* Get the filters available for the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function filters(Request $request)
{
return [];
}
/**
* Get the lenses available for the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function lenses(Request $request)
{
return [];
}
/**
* Get the actions available for the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function actions(Request $request)
{
return [];
}
}
The quick fix for this is this way
Sortable::make('Order', 'id')->exceptOnForms()
I had this problem too, and it was because I had an incoherence between nova fields and migrations fields.
Now, another possible way to fix it is:
php artisan nova:publish
php artisan view:clear
Check this issue for more details: https://github.com/laravel/nova-issues/issues/1735

Laravel Scout and TNTSearch search withTrashed

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();

PHPDoc #return type equals class field type (in PhpStorm 10.0.4)

So I have a trait like as below:
trait RepositoryTrait
{
/**
* Find a model by its primary key.
*
* #param int $id
* #param array $columns
* #return \Illuminate\Database\Eloquent\Model|null
*/
public function find($id, array $columns = ['*'])
{
return $this->query()->find($id, $columns);
}
}
and the interface:
interface Repository
{
/**
* Find a model by its primary key.
*
* #param int $id
* #param array $columns
* #return \Illuminate\Database\Eloquent\Model|null
*/
public function find($id, array $columns = ['*']);
}
and I have repository class like:
class FixedAssetRepository implements Repository
{
use RepositoryTrait;
/**
* FixedAsset model.
*
* #var FixedAsset
*/
protected $model;
/**
* Repository constructor.
*
* #param FixedAsset $fixedAsset
*/
public function __construct(FixedAsset $fixedAsset)
{
$this->model = $fixedAsset;
}
}
and what I'm looking for is to define somehow that method find (in trait or interface) is type of FixedAsset - but this should work always for each new Repository class that I'll create (that implements Repository interface).
I need it for type hinting in PhpStorm 10.0.4
Is it possible somehow?
So the result should be that when I call somewhere I.e.:
$fixedAsset = $this->fixedAssetRepositry->find($id);
PhpStorm will know that $fixedAsset is a object of a class FixedAsset not just \Illuminate\Database\Eloquent\Model (now is working like that).
So I need something that like in interface (or trait?):
/**
* Find a model by its primary key.
*
* #param int $id
* #param array $columns
* #return $this->model
*/
public function find($id, array $columns = ['*']);
but of course #return $this->model doesn't work.
I'll be appreciated for any suggestions about that.
The only solution that I can think of right now would be using #method in PHPDoc comment for that FixedAssetRepository class and "redeclare" that find() method with correct signature (return type). Since it's a PHPDoc solution it will not have any effect on PHP code during runtime.
Sample code:
/**
* #method FixedAsset find(int $id, array $columns) Find a model by its primary key
*/
class FixedAssetRepository implements Repository
{
...
More on the #method tag -- https://github.com/phpDocumentor/fig-standards/blob/master/proposed/phpdoc.md#711-method

PHPDoc return type for MySQL Resource

What is convenient name return type for MySQL resource in PHPDoc?
example i have this code
/**
* Get table data
* #param type $table
* #param type $select
* #param type $condition
* #return mysql_resource
*/
function getResource($table, $field, $condition) {
$resource = mysql_query("SELECT $field FROM $table WHERE $condition ");
return $resource;
}
as you can see #return i write mysql_resource,
is there any convenient name for return mysql resource?
This is typically handled by just "#return resource"... I believe just "resource" matches how var_dump() would show as the object's datatype.

joomla 1.6 component creation error on model

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

Resources