I have a task to convert the standalone PHP files to Magento's MVC. These PHP files were created by another developer. The code in the PHP file accesses the database, converts the result into JSONP format and forward it to the frontend developer.
I don't have any knowledge of Magento's MVC. Is this task of conversion similar to the modules in the app/code/core/Mage in the Magento folder?? How can I do this? Is the magento MVC the same as the PHP MVC?
I am including the php file that I need to convert to Magento MVC. So it will be easier for you to understand..
<?php header('content-type: application/json; charset=utf-8');
$link = mysqli_connect("localhost", "db_username", "password", "db_dbname");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$pid = $_REQUEST['prodid'];
/* Select queries return a resultset */
$result = mysqli_query($link, "SELECT round(rating_summary / 20) AS search_rating FROM review_entity_summary where store_id = 1 and entity_pk_value=" . $pid);
// printf("Select returned %d rows.\n" . "<br>\n", mysqli_num_rows($result)) . "<br>\n";
//$string = $_REQUEST['varname'];
$rows = array();
/* while ($row = $result->fetch_row()) {
printf("%s\n", $row[0]);
}*/
//while($r = mysql_fetch_assoc($result)) {
while ($r = mysqli_fetch_assoc($result)) {
$rows = $r;
//print_r ($rows) . "<br>\n";
}
$json_data = json_encode($rows);
print_r ($json_data);
/* free result set */
// mysqli_free_result($result)
mysqli_close($link);
?>
So how can I convert this file to Magento's MVC style?? IS this necessary to convert this file to magento MVC?
I think what they are asking you to do, is to convert code that look like
require_once 'path/to/magento'. "/Mage.php";
umask(0);
Mage::app("default");
....
In to Magento MVC (module)
\app\code\local\MyNamespace
If you're new to OOP, take a look here: http://www.php.net/manual/en/language.namespaces.rationale.php
\app\code\local\MyNamespace\Appname
Name of new custom module - try to keep at least first letter capital, or there WILL BE truble with Magento's understanding
\app\code\local\MyNamespace\Appname\Block
In classic MVC architecture, this represents View part of MVC
\app\code\local\MyNamespace\Appname\controllers
This is fairly easy to understand, if not, have fun: http://en.wikipedia.org/wiki/Model%E2%80%93View%E2%80%93Controller
\app\code\local\MyNamespace\Appname \etc
Contains the most significant part in Magento's MVC architecture - the xml field that will connect all things together
\app\code\local\MyNamespace\Appname\Helper
Intended for files that contain repeatable routines or simple procedural methods
\app\code\local\MyNamespace\Appname\Model
Same thing as for controller, take a look at the link above
\app\code\local\MyNamespace\Appname\sql
This was interesting thing to find out what's it for, it's to define custom database tables and process any upgrades to your extension.
\etc\modules
Contains all Modules included in Magento - here's where it all really begins for our module
see http://inchoo.net/ecommerce/magento/basic-folder-structure-for-new-magento-module/
Interesting question. IMHO, you are in the position I was with regard to Magento some time ago. To write and use mySql queries against the Magento database requires nothing from the MVC model. In our world, I call these voodoo files. I create tools for my staff with very specific purpose and non-published URLs. You can put them anywhere in the file system, just make sure that the directory name and file name do not have any magic meaning within Magento or you might inadvertently disable some function. My sales tax reporting tool is exactly like yours, where you open a connection to the mySql database and make direct, manual queries against it.
RS's answer is a great primer for getting into the MVC. I have started using it for my voodoo tools as well. Making queries the "Magento way" via their controllers can make getting information out of the EAV much easier than trying to put together the info via manual queries because the infrastructure is already coded for you. An example is customer information! I figured out sales tax queries (which was no minor undertaking), but getting a complete name, address, and email was absurd.
I created an export tool which outputs JSON data. I then CURL it from the server at work to store the sales into a mysql database. From there, they get imported into quickbooks. This order export tool is 100% Magento objects like from the example below.
Here is the code I used in my voodoo customer info tool:
// this limits access to the page to this IP address, perhaps your office?
$remote_host_ip='198.75.43.24';
if( $_SERVER['REMOTE_ADDR'] != $remote_host_ip ){
$error[ date("Y-m-d_H:i:s") ]="\$_SERVER['REMOTE_ADDR'] is ".$_SERVER['REMOTE_ADDR']." which is not the office ip! $remote_host_ip\n";
}
// from: http://fishpig.co.uk/blog/direct-sql-queries-magento.html
require_once '/home/(your host username)/public_html/app/Mage.php';
// from: http://stackoverflow.com/questions/7145373/magento-fatal-error-call-to-a-member-function-getmodelinstance-on-a-non-obje/7145570#7145570
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
$userModel = Mage::getModel('admin/user');
$userModel->setUserId(0);
// from: http://www.magentocommerce.com/boards/viewthread/297092/
$_dealers = Mage::getModel('customer/customer')
->getCollection()
->addFieldToFilter('group_id', array(6,5,3))
// ->addFieldToFilter('group_id', 6)
;
// print_r($_dealers);
$dealers=Array();
foreach( $_dealers as $id => $obj){
// $info=$obj->load();
// print_r($info);
// from: http://www.42droids.co.uk/magento-get-customer-and-address-details
$customerAddressId=$obj->getDefaultBilling();
$address = Mage::getModel('customer/address')->load($customerAddressId);
$_addr=$address->format();
$addr.=",".$address->telephone;
$addr.=",".$obj->email;
echo "$addr\n"; //var_dump($addr);
}
I do most of my learning by google, trial, and error; so please consider that "my way" is simply one that works for me and probably still isn't the best or easiest way. Also, I still don't completely understand how some of the objects work, hence debug output that's commented out.
My advice would be to not try too hard to make something for the "frontend" facing the customer. Getting pages to display and work correctly in Magento is a miserable experience. If you're able to do sneaky hidden voodoo tools, try to do that. If you're forced to make a module, there are a couple dozen step by step how-to's on the net that can guide you.
Related
I'm new to this and I know I'm probably doing this entire thing the wrong way, but I've been at it all day trying to figure it out. I'm realizing there's a big difference between programming a real project of my own rather than just practicing small syntax-code online. So, I lack the experience on how to merge/pass different variables/scopes together. Understanding how to fit everything within the bigger picture is a completely different story for me. Thanks in advance.
What I'm trying to do, is to make the function "selectyacht" output data in a different location from where it's being called (in viewship.php). The output data (in viewship.php) needs to be only certain fields (not everything) returned and those results will be scattered all over the html page (not in a table). In addition to that, I have this variable: "$sqlstatement" (in sqlconn.php) that I'm trying to bring outside the function because I don't want to repeat the connection function every time. I tried a global variable, as much as I shouldn't, and it thankfully it gave me an error, which means I have to find a better way.
Basically my struggle is in understanding how I should structure this entire thing based on two factors:
To allow the second conditional statement in sqlconn.php to be typed
as least often as possible for different "selectyacht" functions
that will come in the future.
To allow the connection instance in sqlconn.php to reside outside the function since it will be used many times for different functions.
Returning data in a different place from where it's being called in viewship.php because the call will be a button press, not the results to be shown.
This is probably very simple, but yet it eludes me.
P.S. Some of this code is a copy/paste from other resources on the internet that I'm trying to merge with my own needs.
sqlconn.php
<?php
$servername = "XXXXXXXX";
$username = "XXXXXXXX";
$password = "XXXXXXXX";
$dbname = "XXXXXXXX";
// Instantiate the connection object
$dbconn = new mysqli($servername, $username, $password, $dbname);
// Check if the connection works or show an error
if ($dbconn->connect_error) {
die("Connection failed: " . $dbconn->connect_error);
}
// Create a query based on the ship's name
function selectyacht($shipname) {
global $sqlstatement;
$sqlstatement = "SELECT * FROM ships WHERE Name=" . "'" . $shipname . "'";
}
// Put the sql statement inside the connection.
// Additional sql statements will be added in the future somehow from other functions
$query = $dbconn->query($sqlstatement);
// Return the data from the ship to be repeated as less as possible for each future function
if ($query->field_count > 0) {
while($data = $query->fetch_assoc()) {
return $data;
}
}
else {
echo "No data found";
}
// Close the connection
$dbconn->close();
?>
viewship.php
<html>
<body>
<?php include 'sqlconn.php';?>
<!-- ship being selected from different buttons -->
<?php selectyacht("Pelorus");?>
<br>
<!-- This is the output result -->
<?php echo $data["Designer"];?>
<?php echo $data["Length"];?>
<?php echo $data["Beam"];?>
<?php echo $data["Height"];?>
</body>
</html>
Mate, I am not sure if I can cover whole PHP coding standards in one answer but I will try to at least direct you.
First of all you need to learn about classes and object oriented programming. The subject itself could be a book but what you should research is autoloading which basically allows you to put your functions code in different files and let server to include these files when you call function used in one of these files. This way you will be able to split code responsible for database connection and for performing data operations (fetching/updating/deleting).
Second, drop mysqli and move to PDO (or even better to DBAL when you discover what Composer is). I know that Internet is full of examples based on mysqli but this method is just on it's way out and it is not coming back.
Next, use prepared statements - it's a security thing (read about SQL injection). Never, ever put external variables into query like this:
"SELECT * FROM ships WHERE Name=" . "'" . $shipname . "'";
Anyone with mean intentions is able to put there string which will modify your query to do whatever he wants eg. erase your database completely. Using prepared statements in PDO your query would look like this:
$stmt = $this->pdo->prepare("SELECT * FROM ships WHERE Name = :ship_name");
$stmt->bindValue(':ship_name', $shipname);
Now to your structure - you should have DB class responsible only for database connection and Ships class where you would have your functions responsible eg. for fetching data. Than you would pass (inject) database connection as an argument to class containing you selectYacht function.
Look here for details how implementation looks like: Singleton alternative for PHP PDO
For
'Returning data in a different place from where it's being called'
If I understand you correctly you would like to have some field to input ship name and button to show its details after clicking into it. You have 2 options here:
standard form - you just create standard html form and submit it with button click redirecting it to itself (or other page). In file where you would like to show results you just use function selectYacht getting ship name from POST and passing it to function selectYacht and then just printing it's results (field by field in places you need them)
AJAX form - if you prefer doing it without reloading original page - sending field value representing ship name via AJAX to other page where you use selectYacht function and update page with Java Script
In the course of a master's thesis I developed an ontology which I imported into Ontotext GraphDB. At this point I need to connect a website (HTML / PHP) with the ontology I imported into Ontotext GraphBD. My technical knowledge is not high so I wondered if it is possible to connect these two components and if yes how can I do it?
I have on one side a website and on the other an ontology in GraphDB. Now I need that in this website it is possible for example to do CRUD operations so that these operations are also done in the ontology that is in Ontotext GraphDB.
Example: Consult through my website all the individuals present in the ontology.
I in the Ontotext GraphDB workbench through the Sparql queries I get these operations, but I want to do it through the website that I'm doing in HTML, PHP and CSS.
Thanks for your attention.
Best regards
I think I solved my problem with this here.
In general, you need to download Semsol's ARC2 library.
Then you create the php file with a structure like this:
<?php
/* ARC2 static class inclusion */
include_once('semsol/ARC2.php');
$dbpconfig = array(
"remote_store_endpoint" => "http://dbpedia.org/sparql",
);
$store = ARC2::getRemoteStore($dbpconfig);
if ($errs = $store->getErrors()) {
echo "<h1>getRemoteSotre error<h1>" ;
}
$query = '...';
/* execute the query */
$rows = $store->query($query, 'rows');
if ($errs = $store->getErrors()) {
echo "Query errors" ;
print_r($errs);
}
/* display the results in an HTML table */
echo "..."
?>
I thank everyone who tried to help me.
You need to somehow query your GraphDB from your PHP application using a remote sparql service. If this is what you want, in java, this can be easily done using Jena QueryExecutionFactory.sparqlService method.
However, a simple googling for PHP results in A PHP forward proxy for remote access to SPARQL endpoints. Where you can send queries and receive results from a SPARQL endpoint, I guess this is what you actually need.
Furthermore, this link gives you multiple options for SPARQL implementations including some php ones.
I'm trying to get the country from which the user is browsing the website so I can work out what currency to show on the website. I have tried using the GET scripts available from: http://api.hostip.info but they just return XX when I test it.
If anyone knows any better methods please share.
Thanks.
I use this:
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
$ip = $_SESSION['ip'];
$try1 = "http://ipinfodb.com/ip_query.php?ip=".$ip."&output=xml";
$try2 = "http://backup.ipinfodb.com/ip_query.php?ip=".$ip."&output=xml";
$XML = #simplexml_load_file($try1,NULL,TRUE);
if(!$XML) { $XML = #simplexml_load_file($try2,NULL,TRUE); }
if(!$XML) { return false; }
//Retrieve location, set time
if($XML->City=="") { $loc = "Localhost / Unknown"; }
else { $loc = $XML->City.", ".$XML->RegionName.", ".$XML->CountryName; }
$_SESSION['loc'] = $loc;
Try these:
http://ip-to-country.webhosting.info/
http://www.ip2location.com/
Both are IP address-to-country databases, which allow you to look up the country of origin of a given IP address.
However it's important to note that these databases are not 100% accurate. They're a good guide, but you will get false results for a variety of reasons.
Many people use proxying to get around country-specific blocks and filters.
Many IP ranges are assigned to companies with large geographic spread; you'll just get the country where they're based, not where the actual machine is (this always used to be a big problem for tracking AOL users, because they were all apparently living in Virginia)
Control of IP ranges are sometimes transferred between countries, so you may get false results from that (especially for smaller/less well-connected countries)
Keeping your database up-to-date will mitigate some of these issues, but won't resolve them entirely (especially the proxying issue), so you should always allow for the fact that you will get false results.
You should use the geoip library.
Maxmind provides free databases and commercial databases, with a difference in the date of last update and precision, the commercial being of better quality.
See http://www.maxmind.com/app/geolitecountry for the free database.
I think it should be sufficient for basic needs.
You can use Geolocation to get the Coordinates and then some Service to get the Country from that, but the geolocation API is browser based so you can only access it via JavaScript and then have to pass theese Informations to PHP somehow, i wrote something on the JS Part once:
http://www.lautr.com/utilizing-html5-geolocation-api-and-yahoo-placefinder-example
When it comes to getting the Location via the IP, there are a bazillion Services out there who offer databases for that, some free, some for charge, some with a lot of IP's stored and much data, some with less, for example the one you mentioned, works just fine:
http://api.hostip.info/?ip=192.0.32.10
So You can ether go with the Geolocation API which is pretty neat, but requires the users permission, works via JS and doesnt work in IE (so far) or have to look for a IPÜ Location Service that fits your needs :)
Try these:
$key="9dcde915a1a065fbaf14165f00fcc0461b8d0a6b43889614e8acdb8343e2cf15";
$ip= "198.168.1230.122";
$url = "http://api.ipinfodb.com/v3/ip-city/?key=$key&ip=$ip&format=xml";
// load xml file
$xml = simplexml_load_file($url);
// print the name of the first element
echo $xml->getName() . "";
// create a loop to print the element name and data for each node
foreach($xml->children() as $child)
{
echo $child->getName() . ": " . $child . "<br />";
}
There are many ways to do it as suggested by those earlier. But I suggest you take a look at the IP2 PHP library available at https://github.com/ip2iq/ip2-lib-php which we developed.
You can use it like below:
<?php
require_once("Ip2.php");
$ip2 = new \ip2iq\Ip2();
$country_code = $ip2->country('8.8.8.8');
//$country_code === 'US'
?>
It doesn't need any SQL or web service lookup just a local data file. It is faster than almost all other methods out there. The database is updated monthly you can download it for free.
The only thing you will need to do for now if you need the country name in your language is map it to an associative array from something like this https://gist.github.com/DHS/1340150
I have somewhat of a knowledge of the PHP coding language and I would like to connect the Campaign Monitor API(Link) with my website, so that when the user enters something into the form on my site it will add it to the database on the Campaign Monitor servers. I found the PHP code example zip file, but it contains like 30 files, and I have no idea where to begin.
Does anyone know of a tutorial anywhere that explains how to connect to the API in a step-by-step manner? The code files by themselves include to much code that I may not need for simply connecting to the database and adding and deleting users, since I only want to give the user the power to add and delete users from the Mailing List.
This actually looks pretty straightforward. In order to use the API, you simply need to include() the CMBase.php file that is in that zip file.
Once you've included that file, you can create a CampaignMonitor object, and use it to access the API functions. I took this example out of one of the code files in there:
require_once('CMBase.php');
$api_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$client_id = null;
$campaign_id = null;
$list_id = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$cm = new CampaignMonitor( $api_key, $client_id, $campaign_id, $list_id );
//This is the actual call to the method, passing email address, name.
$result = $cm->subscriberAdd('joe#notarealdomain.com', 'Joe Smith');
You can check the result of the call like this (again taken from their code examples):
if($result['Result']['Code'] == 0)
echo 'Success';
else
echo 'Error : ' . $result['Result']['Message'];
Since you're only interested in adding a deleting users from a mailing list, I think the only two API calls you need to worry about are subscriberAdd() and subscriberUnsubscribe():
$result = $cm->subscriberAdd('joe#notarealdomain.com', 'Joe Smith');
$result = $cm->subscriberUnsubscribe('joe#notarealdomain.com');
Hope that helps. The example files that are included in that download are all singular examples of an individual API method call, and the files are named in a decent manner, so you should be able to look at any file for an example of the corresponding API method.
I have the website written in PHP (Kohana) and MySQL. I want to create the installer which would run all the environment tests and, what is the most important (and the most misterious) for me, will deploy the database. What is more, I would like to choose the prefix of the tables in the database and specify the username and password for the admin. Would you please give my some hints how to do it? Or some link to some tutorial? I was trying to google that but when I searched for terms like "PHP website installer" I have found only how to install PHP.
The most important for me is the process of deploying database with user-defined tables prefix. How should I store the database structure in the file. Should I name the tables using some keyword for the prefix, for example:
%%prefix%%_tableName
or
__prefix__tableName
And what then? Change all the keywords using regular expresions? Is it correct way or is it any better?
A simple way would be to store the SQL queries in PHP files and have PHP inject the prefix into the SQL and return the string.
Like, if you had a PHP file like this for each of your CREATE TABLE queries:
<?php
/** get_myTable.php **/
return <<<SQL
CREATE TABLE `{$prefix}myTable` ( ... )
SQL;
?>
You could do this in your main code:
<?php
$prefix = 'dbprefix_';
$create_queries = array();
$create_queries[] = include('get_myTable.php');
$create_queries[] = include('get_otherTable.php');
foreach($create_queries as $_query) {
mysql_query($_query) or trigger_error(mysql_error(), E_USER_WARNING);
}
?>
Wordpress has its famous '5-minute install'. It's a great benchmark for simplicity, usability, and power and it does most, if not all, of the things you outlined in your question.