I'm using CodeIgniter 3.1.0 to develop an app.
In order to improve its installation, I've written an Install_Controller, and an Install_Model. I'm using Database Forge class to manage the database. Thanks to it, I can create a DB, but I can't check before if it exists. Actually, my idea was to pass a query to dbforge, like "CREATE DATABASE IF NOT EXISTS mydatabase". I've search the doc but there wasn't any function that could meet my requirements. Where can I write such a query ?
Here is an excerpt from the former :
$this->load->model('Install_Model');
$this->Install_Model->launchInstall();
Here is the code of the latter :
class Install_Model extends CI_Model {
public function __construct() {
parent::__construct();
$this->load->dbforge();
}
public function index() {
if ($this->dbforge->create_database('mydatabase'))
{
echo "OK";
}
else {
echo "Error somewhere";
}
$this->load->database('mydatabase');
}
}
you can use this custom SQL query function within your installation script to create new database.
public function createDB($databse) {
$strSQL = "CREATE DATABASE IF NOT EXISTS $databse";
$query = $this->db->query($strSQL);
if (!$query) {
throw new Exception($this->db->_error_message(),
$this->db->_error_number());
return FALSE;
} else {
return TRUE;
}
}
Related
I have a model with boot function which has created event like below.
However, I sometimes (not all the time) get No query results for model on ProcessAddressRefine which is a job. As far as I understand, created event should happen after record is created, so there is no way that there is no query result unless it gets deleted right after it has been created. I also wonder that looking at the DB record, ProcessAddressRefine job is properly executed.
What would be the problem in this case?
Any advice or suggestion would be appreciated. Thank you.
Model
public static function boot()
{
parent::boot();
self::created(function ($model) {
if (!$model->lat || !$model->lng) {
ProcessAddressRefine::dispatch($model);
}
});
}
Job
class ProcessAddressRefine implements ShouldQueue
{
use Dispatchable, SerializesModels;
private $place;
public function __construct($place)
{
$this->place = $place;
}
public function handle()
{
if ($this->place->addressRefine()) {
$this->place->save();
}
}
}
Extra
public function addressRefine()
{
$helper = new MapHelper();
$coordinate = $helper->addressToCoordinate($geo_code_address);
if ($coordinate !== false) {
$this->lat = $coordinate['lat'];
$this->lng = $coordinate['lng'];
return true;
} else {
return false;
}
}
Assuming job is queued it's quite possible that model is created, then you dispatch the job, then model is deleted and then job is really executed and you are getting this message because model doesn't exist any more.
This was because of DB::transaction when Order record is created.
In laravel I want to call a function within function to make recursive.I caught the route error.how to call the function 'recursive in tableFetch'
class queryTest extends Controller
{
public function tableFetch() {
recursive();
}
function recursive(){
//condition
}
}
I want to do it for check the manager of the given person and then get the manager of the fetched value in query so need to do it recursive
A controller is not a good place for this. Instead, manage it in your Person Model(or whatever you have).
Everyone has a manager. So, your model has HasOne relation to itself.
Person Model:
public function manager()
{
return $this->hasOne(Person::class, 'manager_id');
}
Now if you need to check the manager of given person untill you meet a certain condition you can do it inside the model and get the result in the controller.
public function checkManager()
{
$manager = $this->manager
if (check manager)
return $manager;
//check for the last manager
return $this->manager ? $this->checkManager() : null;
}
Inside controller
function index()
{
$person = Person::find($id);
$manager = $person->checkManager();// this will do the recursive you need
}
Do something like this
class queryTest extends Controller
{
public function tableFetch() {
$this->recursive();
}
function recursive(){
//condition
}
}
you need to ask more precise details about your needs, because Laravel has some complications.
try doing this :
class queryTest extends Controller
{
public function tableFetch() {
$this->recursive();
}
public function recursive() {
//condition
}
}
I have a plugin in october and i'm creating the neccessary tables and seeding them per the docs.
I wish to provide console output when doing that so I can debug the process i'm setting up and catching any eventualities.
How can I output information to console when running php artisan october:up?
use Db;
use Seeder;
class SeedGeoStateTable extends Seeder
{
public function run()
{
foreach(array_merge(glob(__DIR__.'/seed/geo_state/*.txt'), glob(__DIR__.'/seed/geo_state/*.json')) as $file) {
$this->insert($file);
gc_collect_cycles();
}
}
public function insert($file) {
// output to console which file i'm seeding here
$json = json_decode(file_get_contents($file),true);
foreach($json as $entry) {
Db::table("geo_state")->insert($entry);
}
}
}
In your seeder you have the command property available, with the following methods available:
$this->command->info($message)
$this->command->line($message)
$this->command->comment($message)
$this->command->question($message)
$this->command->error($message)
$this->command->warn($message)
$this->command->alert($message)
To see all available methods check Illuminate\Console\Command.
Example
public function run()
{
$this->command->comment('Seeding GeoState...');
foreach(array_merge(glob(__DIR__.'/seed/geo_state/*.txt'), glob(__DIR__.'/seed/geo_state/*.json')) as $file) {
$this->insert($file);
gc_collect_cycles();
}
}
By using the Symfony class ConsoleOutput
$output = new \Symfony\Component\Console\Output\ConsoleOutput(2);
$output->writeln('hello');
This will output information to console.
In the examples case
use Db;
use Seeder;
class SeedGeoStateTable extends Seeder
{
public function run()
{
foreach(array_merge(glob(__DIR__.'/seed/geo_state/*.txt'), glob(__DIR__.'/seed/geo_state/*.json')) as $file) {
$this->insert($file);
gc_collect_cycles();
}
}
public function insert($file) {
// output to console which file i'm seeding here
$output = new \Symfony\Component\Console\Output\ConsoleOutput(2);
$output->writeln("Seeding table with file $file");
$json = json_decode(file_get_contents($file),true);
foreach($json as $entry) {
Db::table("geo_state")->insert($entry);
}
}
}
When updating a user's account, what is the best way to only allow the user itself and the admin to do so?
I use multiauth and the only way I can think of is:
public function update($id)
{
if (Auth::admin()->check() || Auth::user()->get()->id == $id)
{
// Allow update
}
}
Is there a cleaner way to do so?
Where you put this code depends on your architecture.
If it's a simple setup, the model might be the perfect place for it:
class User extends Eloquent implements .... {
protected static function boot($id)
{
static::updating(function($user)
{
return $user->canCurrentUserUpdate();
});
}
protected function canCurrentUserUpdate()
{
return Auth::admin()->check() || Auth::user()->get()->id == $this->id;
}
}
CodeIgniter 2.1.2
I have a class that contains two methods, for the purpose of this questions showone and view. The latter returns all items of a small database and can also perform a search. The other one is for permalinks like domain.com/showone/firstname-lastname
<?php
class Pages extends CI_Controller {
public function view($page)
{
//this includes a mysql search
}
public function showone($slug)
{
//abbreviated version:
$query = "SELECT * FROM mytable WHERE slug = '" . $slug . "'";
$result = $this->db->query($query);
if ($result->num_rows() == 0)
{
//here is where I'd like to use the same search that I used in showall
}
else
{
//show the one item
}
}
} //class
?>
So if a user decides to directly enter a URL that doesn't return anything from the database, I would like to direct him to search results instead of showing a 404.
So how do I set up a function searchdatabase($query) to be used by both showone and view?
You can use your controller functions inside your controller:
public function view($page)
{
$this->showone($slug);
}
Define that function in your model, load your model and then call the model->method.
<?php
//Your Model would look something like this.
class Search_Model extends CI_Model {
public function __construct(){
parent::__construct();
}
public function showone($slug)
{
//abbreviated version:
//Its best to use active record for building your queries
$this->db->where->('slug', $slug);
$result = $this->db->get('mytable');
if ($result->num_rows() == 0)
{
//here is where I'd like to use the same search that I used in showall
}
else
{
//show the one item
}
}
} //class
And then in your controller you would do this:
<?php
//Your Controllerwould look something like this.
class Index extends CI_Controller {
public function __construct(){
parent::__construct();
//model will be loaded for each method.
//if you're going to use this model across several controllers
//its best to autoload it, set that in autoload.php under /app/config
$this->load->model('search_model');
}
public function index(){
$searchResults = $this->search_model->showone('slugone');
}
Update
I just realized you are wanting to show all results if no results were returned. In which case you would perform that logic in your model as well..
In your conditional statement you would do the following:
if ($result->num_rows() == 0)
{
return $this->showall();
}
else
{
return $this->view($slug);
}
}
your showall() and view() methods would return $result->result();