How to convert from a string to className in PHP Symfony(Doctrine) - doctrine

in order to get data from db Im using repo. My current code is working great but I want to update it to use for multiple purpose.
$objectData = $em->getRepository(Articles::class)->findBy(['id' => $modelDataArray['id']]);
so, what I need is something like this:
$moduleName = 'Articles';
$className = $moduleName . '::class';
$objectData = $em->getRepository($className)->findBy(['id' => $modelDataArray['id']]);
but because $className is string will throw an error
Class "Articles::class" does not exist
because its looking for "Articles::class" not Articles::class

Related

$_SESSION variables use in queries

I have spent nearly two days going in circles on this one.
I seem to have difficulty using $_SESSION or $_POST as strings in any query or converting them to strings to use.
I am using a simple hash approach to login to a site.
Extract from script is
<?php
session_start();
echo "******Running Authenticate<br>";
echo "data submitted<br>".$_POST['site_login']."<br>".$_POST['site_password']."<br><br>";
$SiteLogin = $_POST['site_login']
$_SESSION['site_login'] = $_POST['site_login'];
$_SESSION['site_password'] = $_POST['site_password'];
$_SESSION['session_id'] = session_id();
$_SESSION['Now_val'] = date('Y-m-d H:i:s');
//include 'showallvars.php';
include 'dbconfig.php';
// Prepare our SQL
if ($stmt = $con->prepare('SELECT site_index, site_password FROM web_sites WHERE site_login = ?')) {
// Bind parameters (s = string, i = int, b = blob, etc), hash the password using the PHP password_hash function.
$stmt->bind_param('s', $_POST['site_login']);
$stmt->execute();
$stmt->store_result();
// Store the result so we can check if the account exists in the database.
if ($stmt->num_rows > 0) {
$stmt->bind_result($id, $password);
$stmt->fetch();
echo "account exists";
}
else
{
header('Location: badindex.php');
}
if (password_verify($_POST['site_password'], $password)) {
// Verification success! User has loggedin!
echo "password good";
}
else
{
header('Location: badindex.php');
}
}
$_SESSION['loggedin'] = TRUE;
?>
that works fine
BUT there is another field ( 'site_name') in the record which i want to carry forward.
This should be easy !!
and there is a dozen ways of doing it
for example the "standard" example is something like
$name = $mysqli->query("SELECT site_name FROM web_sites WHERE site_login = 'fred'")->fetch_object()->site_name;
That works fine
but no matter how i try - concatenating or or ... I cannot get $_SESSION['site_login'] or $_POST['site_login'] to replace 'fred'.
There seems to be white space added in.
Assistance or guidance ?
It should be possible to as easy as doing the following:
So:
if ($stmt = $con->prepare('SELECT site_index, site_password
FROM web_sites WHERE site_login = ?')) {
becomes:
if ($stmt = $con->prepare('SELECT site_index, site_password, site_login
FROM web_sites WHERE site_login = ' . $SiteLogin)) {
Do note, it is bad practice to do directly parse $SiteLogin to a query, because now someone can SQL Inject this and hack your website. All they need to do is use your form and figure out that which field is responsible for $SiteLogin. You would need to escape your $SiteLogin. Assuming Mysqli, it would become:
if ($stmt = $con->prepare('SELECT site_index, site_password, site_login
FROM web_sites WHERE site_login = ' . $con->real_escape_string($SiteLogin))) {
Thank you for that BUT the instant I saw the curly brackets in your answer - it all came flooding back to me. I had forgotten that PHP has problems with the square brackets
$sql = ("SELECT site_name FROM web_sites WHERE site_login = '". $_SESSION{'site_login'} ."' LIMIT 1");
I KNEW it was easy !
Your comments on injection are of course correct but this was an edited code excerpt and $SiteLogin was just added in as a "temporary working variable if needed"

Laravel easier way to save multiple input fields to database

I am trying to save a long form data to database. Till now i am getting the form value from request object and setting it to database model.
This works perfectly fine. But I want to know if there is another way to initialise the model efficiently without need to set each value. My model has one to one relation.
I have been doing like this. But i don't think this is the right way to do
//Student details
$studentDetail->student_first_name = $request->input('studentFirstName');
$studentDetail->student_last_name = $request->input('studentLastName');
$studentDetail->student_phone_number = $request->input('studentPhoneNumber');
$studentDetail->student_date_of_birth = $request->input('studentDOB');
$studentDetail->student_email = $request->input('studentEmail');
$studentDetail->save();
$studentAddress = new Address();
$studentAddress->address_1 = $request->input('studentAddress1');
$studentAddress->address_2 = $request->input('studentAddress2');
$studentAddress->city = $request->input('studentCity');
$studentAddress->state = $request->input('studentState');
$studentAddress->country = $request->input('studentCountry');
$studentAddress->post_code = $request->input('studentPostCode');
$studentDetail->addresses()->save($studentAddress);
$visaDetails = new Visa();
$visaDetails->passport_number = $request->input("visaPassportNumber");
$visaDetails->visa_number = $request->input("visaVisaNumber");
$visaDetails->visa_class = $request->input("visaVisaClass");
$visaDetails->visa_grant_date = $request->input("visaVisaGrantDate");
$visaDetails->visa_expiry_date = $request->input("visaVisaExpiryDate");
$studentDetail->visaDetails()->save($visaDetails);
//
$instituteDetails = new Institute();
$instituteDetails->institute_name = $request->input("instituteName");
$instituteDetails->institute_location = $request->input("instituteLocation");
$instituteDetails->institute_phone1 = $request->input("institutePhone1");
$instituteDetails->institute_phone2 = $request->input("institutePhone2");
$instituteDetails->institute_email = $request->input("instituteEmail");
// dd($instituteDetails->courses);
$courseDetails = new Course();
$courseDetails->course_level = $request->input("courseLevel");
$courseDetails->course_name = $request->input("courseName");
$courseDetails->course_fee = $request->input("courseFee");
$courseDetails->course_concession_fee = $request->input("courseConcessionFee");
$courseDetails->course_duration = $request->input("courseDuration");
$courseDetails->course_commencement_date = $request->input("courseCommencementDate");
$studentDetail->instituteDetails()->save($instituteDetails);
$instituteDetails->courses()->save($courseDetails);
Any idea on making this process faster??
Simply set create your models using mass assignment, so:
So in your model StudentDetail:
class StudentDetail{
protected $fillable = [
'student_first_name',
'student_last_name',
'student_phone_number',
'student_date_of_birth',
'student_email',
];
//...
//... rest of your model
}
Then tweak your HTML inputs to have in their names the user array like so for example:
<input type="text" id="foo" name="student[student_first_name]">
<input type="text" id="foo" name="student[student_last_name]">
.....
Tip: for validation, you have to treat it with dot notation, so your rule could be:
'student.student_first_name' => 'required|humanName|string|max:255',
Now simply do the following in your controller:
$studentDetail = StudentDetail::create($request->input('student'));
Now you made do the same for your address and other models.
The GIST: After mass assignment enabled for your models you could end up having ONLY the following couple lines of code doing it all for you and it's way more fun and full of dynamism ;) IMHO!
$relatedModels = ['Address', 'Visa', 'Institute', 'Course'];
foreach ($relatedModels as $relatedModel) {
$relatedModelClass = 'App\\'.$relatedModel; //adjust the namespace of your models here.
$ormRelatedModel = $relatedModelClass::create(strtolower($request->input($relatedModel)));
$studentDetail->{strtolower(str_plural($relatedModel)) . 'Details'}()->save($ormRelatedModel);
}
please note that in this case your relations names should be changed a bit like addresses function within your StudentDetail class/model should be changed to addressesDetails or just remove the .'Details' from my sample code above and remove it from your other relations names, i.e: change instituteDetails() to institute(). and make the relation names plural please!
I just tested it and it's working,
Cheers!

How to set Component parameters in J2.5?

I've created a J2.5 component with some config fields using config.xml in the admin folder of the component.
How can I set parameters in the config programatically?
I've tried the code bellow, but it obviously doesn't save the result to the DB:
$params = & JComponentHelper::getParams('com_mycomponent');
$params->set('myvar', $the_value);
Could anyone please show some examples of how to achieve this?
The safest way to do this would be to include com_config/models/component.php and use it to validate and save the params. However, if you can somehow validate the data params yourself I would stick with the following (much more simple solution):
// Get the params and set the new values
$params = JComponentHelper::getParams('com_mycomponent');
$params->set('myvar', $the_value);
// Get a new database query instance
$db = JFactory::getDBO();
$query = $db->getQuery(true);
// Build the query
$query->update('#__extensions AS a');
$query->set('a.params = ' . $db->quote((string)$params));
$query->where('a.element = "com_mycomponent"');
// Execute the query
$db->setQuery($query);
$db->query();
Notice how I cast the params to a string (when building the query), it will convert the JRegistry object to a JSON formatted string.
If you get any caching problems, you might want to run the following after editing the params:
From a model:
$this->cleanCache('_system');
Or, else where:
$conf = JFactory::getConfig();
$options = array(
'defaultgroup' => '_system',
'cachebase' => $conf->get('cache_path', JPATH_SITE . '/cache')
);
$cache = JCache::getInstance('callback', $options);
$cache->clean();
The solution is here...
http://www.webtechriser.com/tutorials/82-joomla-3-0/86-how-to-save-component-parameters-to-database-programmatically
You can replace in Joomla 2.5+ the
// check for error
if (!$table->check()) {
$this->setError('lastcreatedate: check: ' . $table->getError());
return false;
}
if (!$table->store()) {
$this->setError('lastcreatedate: store: ' . $table->getError());
return false;
}
with
if (!$table->save()) {
$this->setError('Save Error: ' . $table->getError());
return false;
}

Make in_array like query with MongoDB in PHP

I am building a web app and in this app (Codeigniter and MongoDB) I let people search files by tags. For example if they enter the tags house and cat they get all files matching them. The tags are collected in an array ($tags).
This is how I do the find query:
select ($select) -> where_in_all ('tags', $tags) -> get ('uploaded_files');
The above query works fine but I really need to let the users search by partial tags. Like "hou" instead of "house". I know how to make a like query but only for one tag at a time. How can I make the in_array search work?
I am using the excellent MongoDB wrapper by vesparny. This is the code in that wrapper for a normal in_array search:
public function where_in_all($field = "", $in = array()){
$this->_where_init($field);
$this->wheres[$field]['$all'] = $in;
return ($this);
}
This is my attempt at modifying it which does not work:
public function where_in_all_like($field = "", $in = array()){
$this->_where_init($field);
$this->wheres[$field]['$all'] = new MongoRegex('/'.$in.'/i');
return ($this);
}
What am I doing wrong?
The wrapper can be found here:
https://github.com/vesparny/cimongo-codeigniter-mongodb-library
Thankful for all help!
Update
This seems to work BUT only on my local server... Not on the production server.
public function where_in_all_like($field = "", $in = array()){
$newarray = array ();
foreach ($in as $value) {
array_push ($newarray, new MongoRegex('/'.$value.'/i'));
}
$this->_where_init($field);
$this->wheres[$field]['$all'] = $newarray;
return ($this);
}
Update 2
I updated MongoDB on my server to 2.0.4 and it works fine now.

Magento - get bundled products where a simple product belongs to

I want to show all bundles on a simple product's page and so need to retrieve the information. I searched and tried a lot. This post sounds promising, but is either not working or maybe not for my problem:
Magento - get a list of bundled product ids from a product id
I found a solution for grouped products but this can't be applied here.
$grouped_product_model = Mage::getModel('bundle/product_selection');
$groupedParentId = $grouped_product_model->getParentIdsByChild($product->getId());
I found the table catalog_product_bundle_selection to be the right place to search, but I wonder if there is a clean way and existing function to search this table by product_id than just to hack this.
I didn't find a solution in Mage_Bundle.
What did I miss?
After getting first aid from vrnet I wrote a new block class, so I can update the layout
class Thomaier_Catalog_Block_Product_View_BundledSelect extends Mage_Catalog_Block_Product_View
{
protected $_simpleProducts = array( '3' ); // just an example
public function getBundles() {
$bundleIds = array();
$bundlesCollectionModel = Mage::getResourceModel('bundle/selection_collection');
$bundlesCollection = $bundlesCollectionModel->getSelect()
->where('`selection`.`product_id` in (' . join(',', (array)$this->_simpleProducts) . ')');
foreach ($bundlesCollection as $bundleItem) {
$bundleIds[] = $bundleItem->getParentProductId();
}
...
}
}
I skipped some parts. As I mentioned in the comment, the SQL query works fine when I try it in phpmyadmin, but $bundleItem is not created and ->load() throws an exception.
Thanks for advice.
Below is a method I wrote for a client having the same request with an extra : the ability to shuffle the result.
Hope it helps.
protected $_simpleProducts = array(); // Array with IDs of simple products you want bundles from.
protected $_shuffle = false;
public function getBundles() {
$bundleIds = array();
/*Rather than using a collection model
and make operations with getSelect,
a more elegant way is to extend
Mage_Bundle_Model_Mysql4_Selection_Collection
with a method that would be something like
setProductIdsFilter($productIds)*/
$bundlesCollectionModel = Mage::getResourceModel('bundle/selection_collection');
$bundlesCollection = $bundleCollectionModel->getSelect()
->where('`selection`.`product_id` in (' . join(',', (array)$this->_simpleProducts) . ')');
foreach ($bundlesCollection as $bundleItem) {
$bundleIds[] = $bundleItem->getParentProductId();
}
if (count($bundleIds)) {
$allowBundles = Mage::getResourceModel('catalog/product_collection')
->addIdFilter($bundleIds)
->addFieldToFilter('status', Mage_Catalog_Model_Product_Status::STATUS_ENABLED);
if ($this->_shuffle) {
$allowBundles->getSelect()->order('rand()');
}
if ($allowBundles->count()) {
return $allowBundles;
}
}
return;
The following is the best way to work with these. This way you do not rely on a custom query but instead you can use the core methods:
$bundlesCollection = Mage::getResourceModel('bundle/selection')
->getParentIdsByChild($simple_product_ids_array_or_int);
foreach ($bundlesCollection as $bundleProdId) {
//do anything you want with the bundleProdId array elements
}

Resources