How to execute query in phalcon model - phalcon

iam using phalcon, I tried to execute query from controller, query run my model
<?php
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Query;
class CakupanBu extends Phalcon\Mvc\Model
{
public static function getJenisBU()
{
header("Access-Control-Allow-Origin: *");
header('Content-type:application/json;charset=utf-8');
$data = array();
$query = new Query(
'SELECT id_jenis_bu,count(jumlah_bu) as jumlah FROM CakupanBu group by id_jenis_bu',
$this->getDI()
);
// Execute the query returning a result if any
$jbus = $query->execute();
foreach ($jbus as $jbu) {
$data[] = array(
'id_jenis' => $jbu->id_jenis_bu,
'jumlah' => $jbu->jumlah,
);
}
return json_encode($data);
}
}
But sadly this is not working, and I ended up with an error.
<b>Fatal error</b>: Uncaught Error: Using $this when not in object context in 'CakupanBU.php:14'
from controller i call :
$jbus=CakupanBU::getJenisBU();
Could anyone give me solution? thanks you

Your function is static, so there is no $this.
To get the DI, you would replace your $this->getDI() with \Phalcon\DI::getDefault()

Related

Error in Laravel Test when I tried to logout an logged user:

I'm facing some problem when I attempt to run a test for know if a user can do logout properly. I'm stuck since one day ago and I can't find the answer in any place.
I'm calling to the route('api.logout') the response is a 500 error and the error says I'm trying to using the method delete() on null.
This is my test file:
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Database\Eloquent\Factory;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Symfony\Component\HttpFoundation\Response;
use Tests\TestCase;
class AuthControllerTest extends TestCase
{
use RefreshDatabase, WithoutMiddleware;
private array $userData;
public function setUp(): void
{
parent::setUp();
$this->userData = [
'email' => 'admin#mydomain.com',
'password' => '12345633',
'password_confirmation' => '12345633',
'name' => 'admin',
'remember_me' => true
];
}
public function test_can_register_a_user(): void
{
$response = $this->post(route('api.register'), $this->userData);
$response->assertStatus(Response::HTTP_OK);
$content = $response->json();
$this->assertNotNull($content['id']);
}
public function test_can_login_a_user(): void
{
$this->test_can_register_a_user();
$response = $this->post(route('api.login', $this->userData));
$response->assertStatus(Response::HTTP_OK);
$content = $response->json();
$this->assertNotNull($content['id']);
}
public function test_can_logout_a_user(): void
{
$this->test_can_login_a_user();
$user = User::where('email', '=', $this->userData['email'])->first();
$this->actingAs($user);
$response = $this->delete(route('api.logout'));
$response->assertStatus(Response::HTTP_OK);
}
}
This is my logout function in the controller:
public function logout(Request $request)
{
$user = auth()->user();
$user->currentAccessToken()->delete();
}
Also I tried doing a Session::start() in test_can_logout_a_user and using $this->be instead of actingAs, but nothing works for me. The $user exists but it doesn't have any tokens. If I run $user->tokens() I got 0 tokens.
I'm using SQLITE type of database and :memory: in the phpunit.xml.
It works fine when I use POSTMAN or INSOMNIA, but it doesn't work when I'm running that test.
Thank you very much.
I'm using Sanctum for authentication
This seems to be a problem with Laravel 9 and Sanctum. I've updated the code in the test and logout function
public function test_can_logout_a_user(): void
{
$user = User::create($this->userData);
$token = $user->createToken('Test token')->plainTextToken;
$response = $this->json('DELETE', route('api.auth.logout'), [], ['Authorization' => "Bearer $token"]);
$response->assertStatus(Response::HTTP_OK);
}
use Laravel\Sanctum\PersonalAccessToken;
.
.
.
.
public function logout(Request $request)
{
$accessToken = $request->bearerToken();
$token = PersonalAccessToken::findToken($accessToken);
$token->delete();
}
In your test you use the WithoutMiddleware meaning and you disable part of the code which you should test and runs in all other cases (postman, insomnia) . Why you need that? You can disabled specifice middlewares with the withoutMiddleware(['name_of_middleware']) but for the login process i don't recomment it.

I am trying to make a dinamic CRUD with PDO but I have this error Fatal error: Uncaught Error: Call to a member function prepare() on null [duplicate]

I think I've a problem in understanding how OOP works. I already changed the code that it works, but it isn't the propper way I think. Following scenario (No, I'm not creating a userlogin by myself, its really just for local dev. to understand OOP better):
I've a database.php file:
class Database {
/* Properties */
private $conn;
private $dsn = 'mysql:dbname=test;host=127.0.0.1';
private $user = 'root';
private $password = '';
/* Creates database connection */
public function __construct() {
try {
$this->conn = new PDO($this->dsn, $this->user, $this->password);
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "";
die();
}
return $this->conn;
}
}
So in this class I'm creating a database connection and I return the connection (object?)
Then I have a second class, the famous User class (actually I'm not using autoload, but I know about it):
include "database.php";
class User {
/* Properties */
private $conn;
/* Get database access */
public function __construct() {
$this->conn = new Database();
}
/* Login a user */
public function login() {
$stmt = $this->conn->prepare("SELECT username, usermail FROM user");
if($stmt->execute()) {
while($rows = $stmt->fetch()) {
$fetch[] = $rows;
}
return $fetch;
}
else {
return false;
}
}
}
So thatare my two classes. Nothing big, as you see. Now, don't get confued about the function name login - Actually I just try to select some usernames and usermails from database and displaying them. I try to achieve this by:
$user = new User();
$list = $user->login();
foreach($list as $test) {
echo $test["username"];
}
And here comes the problem. When I execute this code, I get the following error message:
Uncaught Error: Call to undefined method Database::prepare()
And I'm not sure that I really understand what causes this error.
The code works well when I change the following things:
Change $conn in database.php to public instead of private (I think thats bad...? But when its private, I can only execute querys inside of the Database class, I'm right? So should I put all these querys in the Database class? I think that's bad, because in a big project it will get become really big..)
And the second change I've to do is:
Change $this->conn->prepare to $this->conn->conn->prepare in the user.php file. And here I've really no Idea why.
I mean, in the constructor of the user.php I've a $this->conn = new Database() and since new Database will return me the connection object from DB class, I really don't know why there have to be a second conn->
Do not create classes such as your Database class as it's rather useless. It would make sense to create a database wrapper if it adds some extra functionality to PDO. But given its current code, better to use vanilla PDO instead.
Create a single $db instance from either vanilla PDO or your database class.
Pass it as a constructor parameter into every class that needs a database connection
database.php:
<?php
$host = '127.0.0.1';
$db = 'test';
$user = 'root';
$pass = '';
$charset = 'utf8';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$opt = [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
\PDO::ATTR_EMULATE_PREPARES => false,
];
$pdo = new \PDO($dsn, $user, $pass, $opt);
user.php
<?php
class User {
/* Properties */
private $conn;
/* Get database access */
public function __construct(\PDO $pdo) {
$this->conn = $pdo;
}
/* List all users */
public function getUsers() {
return $this->conn->query("SELECT username, usermail FROM user")->fetchAll();
}
}
app.php
include 'database.php';
$user = new User($pdo);
$list = $user->getUsers();
foreach($list as $test) {
echo $test["username"],"\n";
}
output:
username_foo
username_bar
username_baz
Check out my (The only proper) PDO tutorial for more PDO details.

How to pass variables to mpdf?

I want to pass variables $name and $age from my controller to mpdf view page.
However, it gives me an error: Undefined variable: name.
I tried to pass data in three ways:
1) Created separate methods in Controller getName() and getAge() and call them in a view
2) Send the variables while rendering the page
3) trying to query the age and name from Database directly from view.
All three ways didn't give result. 1 and 3 leads to not loaded page and the second one shows Undefined variable: name error.
View:
<div><?= $name; ?></div>
P.S. I also tried to do like:
<div><?echo $name; ?></div>
<div><?php $name; ?></div>
Controller:
public function actionIndex(){
$this->actionCreateMPDF();
$a = Profile::find('age')->where(['user_id'=>\Yii::$app->user->id])->asArray()->one();
$age = $a['age'];
$n = Profile::find('name')->where(['user_id'=>\Yii::$app->user->id])->asArray()->one();
$name = $n['name'];
return $this->render('index',[
'age' => $age,
'name' => $name,
]);
}
public function actionCreateMPDF(){
$b = true;
$mpdf = new mPDF();
$mpdf->WriteHTML($this->renderPartial('index'));
$mpdf->showImageErrors = true;
$mpdf->Output();
exit;
}
If anyone knows what is my problem please help me :3
Need to pass variables to function actionCreatePdf()
public function actionIndex(){
$profileData = Profile::find()
->select(['age', 'name'])
->where(['user_id'=>\Yii::$app->user->id])
->one();
$age = $profileData->age;
$name = $profileData->name;
$this->actionCreateMPDF($age, $name);
return $this->render('index',[
'age' => $age,
'name' => $name,
]);
}
public function actionCreateMPDF($age, $name){
$b = true;
$content = $this->renderPartial('index',[
'age' => $age,
'name' => $name,
]);
$mpdf = new mPDF();
$mpdf->WriteHTML($content);
$mpdf->showImageErrors = true;
$mpdf->Output();
exit;
}

SQL error when using DQL with symfony

I am using symfony framework, and when I tried this DQL methode to recover username for the Fos_user table generated by the FOSUser bundle
namespace UserBundle\Repository;
use Doctrine\ORM\EntityRepository;
class UserRepository extends EntityRepository
{
public function findEmailDQL($email)
{
$query=$this->getEntityManager()
->createQuery("SELECT u.username
FROM UserBundle:User u
WHERE u.id = $email");
return $query->getResult();
}
}
with the controller function
public function findByEmailJsonAction($email)
{
$users=$this->getDoctrine()->getManager()
->getRepository('UserBundle:User')
->findEmailDQL($email);
$serializer = new Serializer([new ObjectNormalizer()]);
$formatted =$serializer->normalize($users);
return new JsonResponse($formatted);
}
I keep getting this error when I try looking for the user with id 127:
An exception occurred while executing 'SELECT u0_.username AS username_0 FROM user u0_ WHERE u0_.id = 127':
SQLSTATE[42S22]: Column not found: 1054 Champ 'u0_.username' inconnu dans field list
:-)
Try this !
$users = $this->getDoctrine()->getRepository("UserBundle:User")->findBy(array("email" => $email));
Or for just one:
$user = $this->getDoctrine()->getRepository("UserBundle:User")->findOneBy(array("email" => $email));
Good luck ! :-)
Symfony EntityRepository create queryBuilder:
class UserRepository extends EntityRepository
{
public function findEmailDQL($email)
{
return $this->createQueryBuilder('u')
->select('u.username')
->where('u.your_stuff_field = :stuff')
->setParameter('stuff' => $email)
->getQuery()
->getSingleResult();
}
}

PDO return $row from a class method

Hey guys I am learning OOP in php. I come across some issue, when I try to customize PDO in my own class. Basically I have tried to return the row and fetch it outside my class. Unfortunately I would not work. I get this error "Call to a member function fetch() on a non-object". Have a look and give me some tips if You can. Many thanks.
$connection = new MySql(DBUSER, DBPASS);
$row = $connection->query("select * from users", "name");
while($row->fetch(PDO::FETCH_ASSOC)){
echo "<p>". $row["name"] ."</p>";
}
And here is how the MySql class look like:
class MySql{
private $dbc;
private $user;
private $pass;
function __construct($user="root", $pass=""){
$this->user = $user;
$this->pass = $pass;
try{
$this->dbc = new PDO("mysql:host=localhost; dbname=DBNAME;charset=utf8", $user, $pass);
}
catch(PDOException $e){
echo $e->getMessage();
echo "Problem z Połączeniem do MySql sprawdź haslo i uzytkownika";
}
}
public function query($query, $c1=""){
$mysqlquery = $this->dbc->prepare($query);
$mysqlquery->execute();
return $row = $mysqlquery->fetch(PDO::FETCH_ASSOC);
/* I WANT TO PERFORM COMENTED CODE OUTSIDE THE CLASS
while($row = $mysqlquery->fetch(PDO::FETCH_ASSOC)){
if($c1!=""){
echo "<p>". $row[$c1] ."</p>";
}
}
*/
}
If you want to return $mysqlquery to iterate over it, you have to return $mysqlquery, not just one row.
Here is a better version of your class, with dramatically improved error handling and security. But still awful configurability though.
class MySql{
private $dbc;
function __construct($user="root", $pass=""){
$dsn = "mysql:host=localhost; dbname=DBNAME;charset=utf8";
$opt = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
);
$this->dbc = new PDO($dsn, $user, $pass, $opt);
}
public function query($query, $data = array()){
$stm = $this->dbc->prepare($query);
$stm->execute($data);
return $stm;
}
}
$connection = new MySql(DBUSER, DBPASS);
$stm = $connection->query("select * from users WHERE name = ?", array("name"));
while($row = $stm->fetch()){
echo "<p>". $row["name"] ."</p>";
}