I have small problem about store, store view and website creation. I create the store on the customer register (one customer has one website, one store view and one store), all is ok, but when there is an error in saving for example store view, other elements in the DB.
The code:
// Root Category
$category = new Mage_Catalog_Model_Category();
$category->setStoreId(0);
$category->save();
// Website
$website = new Mage_Core_Model_Website();
$website->setData(array(
'code' => $codes,
'sort_order' => 10
))->save();
// Create store group (store view)
$storeGroup = new Mage_Core_Model_Store_Group();
$storeGroup->setData(array(
'website_id' => $website->getId(),
'root_category_id' => $category->getId()
))->save();
// Create store
$store = new Mage_Core_Model_Store();
$store->setData(array(
'code' => $codes,
'website_id' => $website->getId(),
'group_id' => $storeGroup->getId(),
));
$store->save();
I need to edit the code so this things will create in transaction and rollback if there is an error. I don't know how to do this, because I need an id after each object save.
ok, solved myself
try {
$write = Mage::getSingleton('core/resource')->getConnection('core_write');
$write->beginTransaction();
$category = Mage::getModel('catalog/category')
->setStoreId(0)
->setName($code)
->setParentId(Mage_Catalog_Model_Category::TREE_ROOT_ID)
->setPath(Mage_Catalog_Model_Category::TREE_ROOT_ID)
->setDisplayMode(Mage_Catalog_Model_Category::DM_PRODUCT)
->setIsActive(TRUE)
->setId(NULL)
->save();
$website = Mage::getModel('core/website')
->setCode($code)
->setName($code)
->setSortOrder(10)
->setId(NULL)
->save();
$storegr = Mage::getModel('core/store_group')
->setWebsiteId($website->getId())
->setName($code)
->setRootCategoryId($category->getId())
->setId(NULL)
->save();
$store = Mage::getModel('core/store')
->setCode('1'.$code)
->setWebsiteId($website->getId())
->setGroupId($storegr->getId())
->setName($code)
->setSortOrder(10)
->setIsActive(TRUE)
->setId(NULL)
->save();
$write->commit();
} catch (Exception $e) {
$write->rollback();
}
Related
I am creating a custom endpoint in wordpress, which should do the following:
1. Create the path (done)
2. call a function, which:
2.1. Gets all the products from WooCommerce and stores them in an array (done)
2.2. Compares the products on WooCommerce with products from an external database and if there is any difference in data, get updated (PUT) by the data from the external DB
2.3. If some products exist on the external DB but do not exist on WooCommerce, create them on WooCommerce (POST)
I have managed to get all the data from WooCommerce via wc_get_products ($args) but I cannot find how to write the PUT and the POST method to update or create products.
If I use Automatic/WooCommerce to push or put products from a standalone file (not from the custom endpoint) works, but if I keep the Automatic/WooCommerce on the custom endpoint it tells me the following:
Failed to connect to localhost port 8000: Connection refused in /var/www/html/wp-content/plugins/wl-api/vendor/automattic/woocommerce/src/WooCommerce/HttpClient/HttpClient.php on line 417
which makes total sense because from the custom endpoint I am already connected to WooCommerce and the Automatic/WooCommerce would attempt to connect again. So are there any methods like wc_get_products but for PUT and PUSH?
//CUSTOM ENDPOINT PHP FILE
add_action('rest_api_init', 'customEndpoint');
function customEndpoint() {
register_rest_route('endpoint', '/transfer', array(
'methods' => 'GET',
'callback' => 'get_data',
));
}
function get_data() {
include "updateOrCreate.php";
}
//updateOrCreate.php
require 'vendor/autoload.php';
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require 'vendor/guzzlehttp/guzzle/src/Client.php';
use Automattic\WooCommerce;
//-----------Connect to the External DB----------
$baseUrl=...;
$externalClient = new GuzzleHttp\Client();
$res = $externalClient->request('GET', $baseUrl, [
"query" => ['fields' => $fields, 'aktiv' => true],
'auth' => ['...', '...']
]);
$articles = json_decode($res->getBody());
//-----------Connect to WooCommerce DB
$wooKey= "...";
$wooSecret= "...";
$wooCommerceBaseUrl = "http://localhost:8000";
$wooCommerceClient = new WooCommerce\Client($wooCommerceBaseUrl,
$wooKey, $wooSecret,
[
'wp_api' => true,
'version' => 'wc/v3',
]
);
//GET all products from WooCommerce
$args = array(
'status' => 'publish',
'limit' => -1,
);
$wooExistingProducts = wc_get_products($args);
$productsForWoo= [];
//check if there are no products on woocommerce:
if(empty($wooExistingProducts)){
foreach ($articles as &$article){
//Create the necessary template to initialize the connections between external products and woocommerce product template
$wooTemplate = [
...
];
array_push($productsForWoo, $wooTemplate);
//CREATE BATCHES OF 10
if(sizeof($productsForWoo) == 10){
$data = [
'create' => $productsForWoo,
];
$wooCommerceClient->post('products/batch', $data);
$productsForWoo = [];
}
}
//As there is a big chance that the last batch will have less than 10 products, push them as well to wooCommerce as a last batch
$data = [
'create' => $productsForWoo,
];
$wooCommerceClient->post('products/batch', $data);
}
// if there are existing products on woocommerce
else{
//Loop through all existing products on the external DB
foreach ($articles as &$article){
$did_match = false;
$wooTemplate = [
...
];
//loop through all products on WooCommerce
foreach ($wooExistingProducts as &$product){
//if the product id from the external db matches the id from an existing product on woocommerce
if(...){
//update that product
$wooCommerceClient->put('products/'.urlencode($product->id), $wooTemplate);
$did_match = true;
break;
}
}
//otherwise, if the product from the external db is not found on the woocommerce database, create it
if(!$did_match){
array_push($productsForWoo, $wooTemplate);
if(sizeof($productsForWoo) == 10){
$data = [
'create' => $productsForWoo,
];
$wooCommerceClient->post('products/batch', $data);
$productsForWoo = [];
}
}
}
//As there is a big chance that the last batch will have less than 10 products, push them as well to wooCommerce as a last batch
$data = [
'create' => $productsForWoo,
];
$wooCommerceClient->post('products/batch', $data);
}
I will deeply appreciate any input related to my issue. Thank you!
To get POST and PUT, you'll need to implement the methods (verbs).
You can use:
$verb = $_SERVER['REQUEST_METHOD'];
echo $verb;
... to test what HTTP request method (PUT vs GET) you're using.
Here's a SO article regarding PHP methods which I have bookmarked and often use when troubleshooting this. The code provided there is pretty clean and a great place to start.
Is there any way to insert a new record if doesn't exist and update the record if exist? the following is the code i using.
public function store(Request $request)
{
$inputs = $request->all();
$this->validate($request,[
'course_code'=>'required'
]);
$batch = $request->batch;
$students = User::select('student_id')->where('batch', $batch)->get();
$course_codes = $inputs['course_code'];
$data=[];
foreach ($students as $student) {
foreach ($course_codes as $course_code) {
$data[]=[
'batch' => $batch,
'student_id' => $student->student_id,
'semester' => $inputs['semester'],
'course_code' => $course_code,
"created_at" => \Carbon\Carbon::now(), # \Datetime()
"updated_at" => \Carbon\Carbon::now() # \Datetime()
];
}
}
DB::table('assign_batches')->insert($data);
return redirect('/admin/assign/batch/create')->with('message', 'A batch has been assigned to courses successfully!');
}
Here is my output when I inserted same records again.
But I want one Student Id may have many Course Code but can not be duplicate. So I want to check if student has same course or courses then skip or update it and insert new records.
Please help me.
Thanks.
Check id if exist then update otherwise insert
if(isset($request->id)){
DB::table('assign_batches')->where("id", $request->id)->update($data);
}else {
DB::table('assign_batches')->insert($data);
}
Use firstOrCreate / firstOrNew
$students = User::firstOrNew(['student_id' => $request->student_id, 'course_code' => $request->course_code]);
$students->foo = $request->foo;
$students->save();
for example if you have a table for every each user to vote once or update his vote;
//give the record to use
$record = request('vote');
//checkif there is a record for user in model
$row = Uservoting::where('user_id',Auth->user()->id)->first;
//if true
if($row!==null){
//update
$row::update(['vote' => $record]);
//if there isn't in model
}else{
//create a new row and insert the value
$new_row = new Uservoting();
$new_row->user_id = Auth->user()->id ;
$new_row->vote = $record ;
$new_row->vote();`
}
hope this work:) {{--if you found any bug just tell me--}}
I'm trying to update my products with dynamic variants. There is no issue in adding or deleting but when I trying to update, every time it updates with the last record on every field.
I'm trying to update dynamic variants where I have inserted...
color - red
shape -square
It's about dynamic form-fields, inserts work properly but when I am trying to update it, it updates the first value with both the filled and the second value with both the field and I won't be able to distinguish the field because of the Blade file returns in form of an array.
When I am trying to update with any value it repeats the last value in both the fields, so the output looks like...
shape-square
shape-square
Controller
<?php
public function updateProducts($id, Request $request)
{
$featured = Input::has('featured') ? true : false;
$product = Product::findOrFail($id);
$product->update(array(
'product_name' => $request->input('product_name'),
'product_qty' => $request->input('product_qty'),
'product_sku' => $request->input('product_sku'),
'price' => $request->input('price'),
'reduced_price' => $request->input('reduced_price'),
'cat_id' => $request->input('cat_id'),
'brand_id' => $request->input('brand_id'),
'featured' => $featured,
'description' => $request->input('description'),
'product_spec' => $request->input('product_spec'),
));
$product->update($request->all());
$variants = VariantsOption::where('products_id', $id)->get();
$test = $request->all();
foreach ($variants as $v) {
$x = $v->id;
foreach ($test['variants_id'] as $key => $attrib) {
$var_name = $test['txt'][$key];
$varid = $attrib;
$variants = new VariantsOption;
$data = array(
'variants_id' => $varid,
'variants_name' => $var_name
);
$variants->where('id', '=', $x)->update($data);
}
}
return redirect('/admin/products/');
}
use following in your class
use Illuminate\Database\Eloquent\ModelNotFoundException;
OR add exception handler within your function
// Will return a ModelNotFoundException if no user with that id
try
{
$product = Product::findOrFail($id);
}
// catch(Exception $e) catch any exception
catch(ModelNotFoundException $e)
{
dd(get_class_methods($e)) // lists all available methods for exception object
dd($e)
}
It looks like product with that $id is not found so on update it is adding new product in database.
I have this existing code snippet that searches list of records specified by its RecordType (e.g. InventoryItem, SalesOrder).
$request = new GetRequest();
$request->baseRef = new RecordRef();
$request->baseRef->type = $type; //Record Type
$request->baseRef->internalId = $internalId; //Internal ID of record
$getResponse = $service->get($request);
if ( ! $getResponse->readResponse->status->isSuccess) {
return 'ERROR';
} else {
return $getResponse->readResponse->record;
}
However, it seems that there's no Shipping Item in the list in RecordType although I can pass an internal ID. My goal here was to get the shipping item details to be used in my computation for creating a sales order (needs to be displayed before submitting).
Will there be a different approach in getting the shipping item record? How?
Shipping Item record is not yet supported in Suitetalk. As an alternate solution you can create a RESTlet instead to get the Shipping Item.
I can now successfully retrieve Shipping items via RESTlets. I uploaded this first as new in the File Cabinet, then added it as a new script. NetSuite does not allow direct upload of script file when creating a new script.
// get_record.js
function get_record(datain)
{
var record = nlapiLoadRecord(datain.recordType, datain.id);
return record;
}
Then used guzzle http library to call the RESTlet.
$url = "https://rest.sandbox.netsuite.com/app/site/hosting/restlet.nl";
$client = new GuzzleHttp\Client();
$authorization = [
'NLAuth nlauth_account='.getenv('NETSUITE_ACCOUNT'),
'nlauth_email='.getenv('NETSUITE_EMAIL'),
'nlauth_signature='.getenv('NETSUITE_PASSWORD'),
'nlauth_role='.getenv('NETSUITE_ROLE')
];
$response = $client->request('GET', $url, [
'headers' => [
'Authorization' => implode(',', $authorization),
'Content-Type' => 'application/json'
],
'query' => [
'script' => '343', //script id
'deploy' => '1',
'recordType' => 'ShipItem',
'id' => '5905' // example of internal id of desired shipping item
]
]);
return json_decode($response->getBody());
How can I pass the model in array format.
I want to pass models in this format from controller to view:-
Users[user_contact]=Contact
Users[user_contact][contat_city]=City
Users[user_contact][contact_state]=state
This is what I am doing
public function actionCreate() {
$user = new Users;
$presContact = new Contacts;
$presCity = new Cities;
$presState = new States;
$contactArr = array();
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if (isset($_POST['Users'])) {
$transaction = CActiveRecord::getDBConnection()->beginTransaction();
$contactArr = CommonFunctions::saveContact($_POST['Users']['user_pres_contact'],'user_pres_contact',$errorArr);
$presContact = $contactArr['contact'];
$presCity = $contactArr['city'];
$presState = $contactArr['state'];
$user->attributes = $_POST['Users'];
$user->user_pres_contact_id = $presContact->contact_id;
if($user->save()){
$transaction->commit();
$this->redirect(array('view', 'id' => $user->user_id));
} else {
$transaction->rollback();
}
}
$this->render('createUser', array(
'Users' => $user,
'Users[\'user_pres_contact\']'=>$presContact,
'Users[\'user_pres_contact\'][\'contact_city\']'=>$presCity,
'Users[\'user_pres_contact\'][\'contact_state\']'=>$presState,
));
}
I am able to access only $users but
I m not able to access $Users['user_pres_contact'] in the view
That's because you are assigning them as strings...
The correct way of doing things would be (btw, what you are asking for can't done literally, it is impossible to assign 2 values to one key):
$user = array(
'user_press_contact' => array(
'contact' => $presContact,
'city' => $presCity,
'state' => $presState,
),
);
$this->render('createUser', array(
'Users' => $user,
));
It will give you $Users['user_press_contact']['contact'] for the name in the view, etc.
You can use
$user->getAttributes() //it returns an array of data.
Hope that's usefull
It is possible to solve this using model relations? You can define a relation from the User model to the City model (e.g. naming it relation_to_city), then you can just assign the user model in the controller
$this->render('view', 'user'=>$user);
and access the city (from the view)
$user->relation_to_city