I'm trying to insert a file into TYPO3 db through frontend using core functions or FileRepository, exactly into sys_file table.
While investigating I've seen few solutions like,
$storageRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\StorageRepository');
$storage = $storageRepository->findByUid(1);
$fileObject = $storage->addFile('/tmp/myfile', $storage->getRootLevelFolder(), 'newFile');
echo $fileObject->getIdentifier(); // Should output "/newFile"
But I still can't find this addFile() in storageRepository class. Am I missing some thing here?
The line $storageRepository->findByUid(1) return a ResourceStorage Object with the Method addFile().
Here is a Documenttion of this class.
https://typo3.org/api/typo3cms/class_t_y_p_o3_1_1_c_m_s_1_1_core_1_1_resource_1_1_resource_storage.html
#mario Thanks. By the way I've achieved what I planned. Here's what I did..
public function uploadFile($uploadedfile) {
$storage = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\StorageRepository');
$filePath = 'uploads/tx_fileupload/'.$uploadedfile['updata']['name'];
$title = $uploadedfile['updata']['name'];
$size = $uploadedfile['updata']['size'];
// Moving the physical file to destined folder
\TYPO3\CMS\Core\Utility\GeneralUtility::upload_copy_move($uploadedfile['updata']['tmp_name'],$filePath);
// Adding a record in sys_file_storage
$fileObject = $storage->createLocalStorage($uploadedfile['updata']['name'],$uploadedfile['updata']['tmp_name'],$filePath,'');
// Inserting file in sys_file
$repositoryFileObject = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->retrieveFileOrFolderObject($filePath);
return $repositoryFileObject;
}
Now moving onto adding corresponding sys_file_reference record.
Related
I wanted to know what the best way is to store single data values in a database. Values you only need one field of.
I have a couple of ideas.
Storing all fields in a single_data_table with a id, key and value column.
Storing it as a json object in the database.
Storing it as an array in the database.
Which one is the best way? Or might there even be better ways?
Or is it just easier to keep single data values as static data on the webpage?
At my current job we use a separate settings table for that, with two columns: key and value. And then there's a simple function to retrieve or save a setting:
function setting($key, $value = null){
$setting = DB::table('settings')->where('key', $key)->first();
if(is_null($value)){
return $setting->value ?? null;
}
if(isset($setting)){
$setting->value = $value;
}else{
$setting = $setting ?: new stdClass();
$setting->key = $key;
$setting->value = $value;
}
DB::table('settings')->insertOrReplace((array) $setting);
return true;
}
It is used like so:
$phone = setting('phone'); // Get the phone setting
$url = setting('url', 'http://example.com'); // Set url setting
im quite new in laravel framework, and im from codeigniter.
I would like to add new key and value from database
static function m_get_promotion_banner(){
$query = DB::table("promotion_banner")
->select('promotion_banner_id','promotion_link','about_promotion')
->where('promotion_active','1')
->get();
if($query != null){
foreach ($query as $key => $row){
$query[$key]['promotion_image'] = URL::to('home/image/banner/'.$row['promotion_banner_id']);
}
}
return $query;
}
that code was just changed from codeigniter to laravel, since in codeigniter there are no problem in passing a new key and value in foreach statement
but when i tried it in laravel i got this following error :
Indirect modification of overloaded element of Illuminate\Support\Collection has no effect
at HandleExceptions->handleError(8, 'Indirect modification of overloaded element of Illuminate\Support\Collection has no effect', 'C:\xampp\htdocs\laravel-site\application\app\models\main\Main_home_m.php', 653, array('query' => object(Collection), 'row' => array('promotion_banner_id' => 1, 'promotion_link' => 'http://localhost/deal/home/voucher', 'about_promotion' => ''), 'key' => 0))
please guide me how to fix this
thank you (:
The result of a Laravel query will always be a Collection. To add a property to all the objects in this collection, you can use the map function.
$query = $query->map(function ($object) {
// Add the new property
$object->promotion_image = URL::to('home/image/banner/' . $object->promotion_banner_id);
// Return the new object
return $object;
});
Also, you can get and set the properties using actual object properties and not array keys. This makes the code much more readable in my opinion.
For others who needs a solution you can use jsonserialize method to modify the collection.
Such as:
$data = $data->jsonserialize();
//do your changes here now.
The problem is the get is returning a collection of stdObject
Instead of adding the new field to the result of your query, modify the model of what you are returning.
So, assuming you have a PromotionBanner.php model file in your app directory, edit it and then add these 2 blocks of code:
protected $appends = array('promotionImage');
here you just added the custom field. Now you tell the model how to fill it:
public function getPromotionImageAttribute() {
return (url('home/image/banner/'.$this->promotion_banner_id));
}
Now, you get your banners through your model:
static function m_get_promotion_banner(){
return \App\PromotionBanner::where('promotion_active','1')->get();
}
Now you can access your promotionImage propierty in your result
P.D:
In the case you are NOT using a model... Well, just create the file app\PromotionImage.php:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class PromotionImage extends Model
{
protected $appends = array('imageAttribute');
protected $table = 'promotion_banner';
public function getPromotionImageAttribute() {
return (url('home/image/banner/'.$this->promotion_banner_id));
}
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'promotion_banner_id','promotion_link','about_promotion','promotion_active'
];
just improving, in case you need to pass data inside the query
$url = 'home/image/banner/';
$query = $query->map(function ($object) use ($url) {
// Add the new property
$object->promotion_image = URL::to( $url . $object->promotion_banner_id);
// Return the new object
return $object;
});
I've been struggling with this all evening, and I'm still not sure what my problem is.
I've used ->get() to actually execute the query, and I've tried by ->toArray() and ->jsonserialize() on the data and it didn't fix the problem.
In the end, the work-around I found was this:
$task = Tasks::where("user_id", $userId)->first()->toArray();
$task = json_decode(json_encode($task), true);
$task["foo"] = "bar";
Using json_encode and then json_decode on it again freed it up from whatever was keeping me from editing it.
That's a hacky work-around at best, but if anyone else just needs to push past this problem and get on with their work, this might solve the problem for you.
I have a product controller and when I'm saving a new product I want to save some records to another related controller to make a record of what categories the product is associated with.
My code I'm using is:
$this->Product->create();
if ($this->Product->save($this->request->data)) {
$newProductId = $this->Product->getInsertID();
//associate products with categories
foreach($categoriesToSave as $key=>$value) {
$saveArray['CategoriesProduct'] = array('category_id'=>$value, 'product_id'=>$newProductId);
$this->Product->CategoriesProduct->create();
$this->Product->CategoriesProduct->save($saveArray);
$this->Product->CategoriesProduct->clear();
}
}
For some reason though, even if $categoriesToSave has 10 items in it, only the very last one is being saved. So it's obviuosly creating only the one new CategoriesProduct item and saving each record over the top of the last instead of create()-ing a new one.
Can anyone explain what I'm doing wrong and how I can make this work?
The way I would do it would be like this:
//Add a counter
$c = 0
foreach($categoriesToSave as $key=>$value) {
$saveArray[$c]['CategoriesProduct']['category_id'] = $value;
$saveArray[$c]['CategoriesProduct']['product_id'] = $newProductId;
$c++;
}
$this->Product->CategoriesProduct->saveMany($saveArray);
I don't think that is the only way to do it but that should work just fine.
Good luck!
My problem is that I will have 1..n files to merge into a single file. I have a target SPFile on the Sharepoint Server. I have written a method based on web sites about OpenXML and it runs without errors but ends up blank when I review it.
Here is the Method
private void InsertSPFileInto(SPFile target, SPFile source, int index)
{
Stream targetStream = target.OpenBinaryStream();
using (WordprocessingDocument myDoc = WordprocessingDocument.Open(targetStream, true))
{
string altChunkId = "AltChunkId" + index.ToString();
MainDocumentPart mainPart = myDoc.MainDocumentPart;
AlternativeFormatImportPart chunk =
mainPart.AddAlternativeFormatImportPart(
AlternativeFormatImportPartType.WordprocessingML,
altChunkId);
Stream sourceStream = source.OpenBinaryStream();
chunk.FeedData(sourceStream);
AltChunk altChunk = new AltChunk();
altChunk.Id = altChunkId;
mainPart.Document
.Body
.InsertAfter(altChunk,mainPart.Document.Body.LastChild);
mainPart.Document.Save();
}
}
Again it just returns a blank document, but it doesn't corrupt it either.
Thanks.
Tim Daniels
After playing around with it I found the problem I need to add the follow three lines to the method after the line "maindocument.Documents.Save()"
targetDoc.Close();
targetStream.Flush();
target.SaveBinary(targetStream);
I am wondering is there an easy way to make a copy of a tree structure that consists of one model with a parent_id that actsAs a tree?
I was thinking it should be easy to recursively go through a given tree, remove all ids and lft, rght fields; however, as I add the new fields parent_id won't match up correctly. I suppose it should be easy enough to write my own function to handle this, but I just wanted to know if there was already something to handle this?
Thanks!!
First, I used Multi Tree Behaviour ( http://bakery.cakephp.org/articles/view/multitree-behavior ) as it allows several trees to be managed in one table.
My examples are perhaps a little complex and confused with application specific code, but I'm sure you can pick your way through it!
Pretty much anything you do with the tree is going to need a recursive 'tree-walker'. I wrote a task manager with sub-tasks etc. and this is an example of a method I used to walk the tree:
function _walkTasksTree($nodes, $model='Task')
{
foreach($nodes as $node)
{
$task = $node[$model];
$id = $task['id'];
$title = $task['name'];
$level = $task['level'];
$children = $this->_walkTasksTree($node['children'],$model);
if(empty($children))
{
$data[$id] = array('level'=>$level,'title'=>$title);
}
else
{
$data[$id] = array('level'=>$level,'title'=>$title,'children' => $children);
}
}
$data = (isset($data))?$data:array();
return $data;
}
My application has a 'repository' of common tasks which can be cloned into a project. The basic model is ProjectTask [1:1] ProjectTaskDescriptor - the descriptor holding the data, and the task holding the tree position. I use this method to traverse and clone trees and/or branches
function _saveTaskTree($subTasks,$parent_id,$root_id,$projId,$exclude=null)
{
foreach($subTasks as $node)
{
if(#$exclude!=$node['Task']['id'])
{
$node['Task']['id'] = null;
$node['Task']['root_id'] = $root_id;
$node['Task']['parent_id'] = $parent_id;
$node['Task']['project_id'] = $projId;
$this->ProjectTask->create();
$saved = $this->ProjectTask->save($node['Task']);
$this->ProjectTaskDescriptor->create();
$PTD = $node['TaskDescriptor'];
$PTD['project_task_id'] = $this->ProjectTask->id;
$this->ProjectTaskDescriptor->save($PTD);
}
else
{
$saved = true; //skip the first one - we've already done it.
}
if($saved)
{
if(#$node['children'])
$children = $this->_saveTaskTree($node['children'],$this->ProjectTask->id,$root_id,$projId);
}
}
}
It is a very hands on process and in terms of future understanding and maintenance of the code it is worthwhile fully understanding what is going on.