I have some problem with zend. Here it is. I'm going to make some kind of articles db, which containt some info. Every article is marked with 1 or more tags (like WordPress).
I have a controller (let it be index) and action (also index).
All I need is to get articles and tags, associated with it, when user goes to site/index/index.
I have 3 tables:
articles(idarticles, title..)
tags(idtags, title)
tagList(idarticles, idtags).
How can I read tags, associated with article?
Zend's MVC doesn't actually include a model, however, the quickstart guide outlines creating a model.
The simplest way (not necessarily the best way), is to setup the connection in your application.ini, or setup the adapter like this (see the Zend_Db_Adapter docs):
$db = new Zend_Db_Adapter_Pdo_Mysql(array(
'host' => '127.0.0.1',
'username' => 'webuser',
'password' => 'xxxxxxxx',
'dbname' => 'test'
));
Then use SQL to select your data.
//all articles
$articles = $db->query('SELECT * FROM articles');
//a article's tags
$tags = $db->query('SELECT * FROM tagList JOIN tags ON
(tagList.idtag = tags.idtags) WHERE idarticles = ?', $idarticles);
This is also taged for Zend_Db_Table, to use that to access the data, first setup a default adapter (or again, use application.ini):
Zend_Db_Table::setDefaultAdapter($dbAdapter);
Then get objects for you tables like this:
$ariclesTable = new Zend_Db_Table('articles');
To get all the articles:
$articles = $articlesTable->fetchAll();
To get an article's tags (little more complex here, using a Zend_Db_Table_Select as recommended):
$select = $tagsTable->select();
//3rd argument must be empty array, so no joined columns are selected
$select->join('tagList', 'tagList.idtag = tags.idtags', array());
$select->where('tagList.idarticles = ?', $idarticles);
$tags = tagsTable->fetchAll($select);
Related
Could anyone please help with the linq for this problem.
Users have a list of Properties and Properties have a list of Users.
I first do a query to get all Properties with a particular CompanyId. This makes a new list which we'll call MyProperties.
I need to get all Tenants that have a property in the MyProperties list.
For other reasons, I don't have access to the "PropertiesUsers" Join table.
Sorry if it looks like I haven't thought this through, I've been banging my head all day on it.
You can use Enumerable.SelectMany() to flatten the hierarchy:
var myProperties = dbContext.Properties.Where(property => property.CompanyId = companyId);
var tenants = myProperties.SelectMany(property => property.Tenants);
Use Intersect:
var myPropertyIds = MyProperties.Select(p => p.PropertyId).ToArray();
var result = Users.Where(u => myPropertyIds.Intersect(
u.Properties.Select(p => p.PropertyId))
.Any());
If you are sure that the properties in both lists are the same instances you could use
var result = Users.Where(u => MyProperties.Intersect(
u.Properties)
.Any());
just wondering if there is a way, using the API, to pull out the post title and desc separately? Essentially I would like this:
$post['author'] = $p['from'];
$post['title'] = $p['?'];
$post['content'] = $p['?'];
thanks
edit. I would also be happy with pulling just the title of a new post...
edit2. my mistake, there is no title in facebook posts. my coffee finally kicked in and my ignorance was revealed to me.
Try this http://www.wescutshall.com/2011/12/getting-facebook-user-data-with-php/
As you can see, you need some special permission from FB to get the data you need.
After that you can use their api, as described in the url before, to get your data.
EDIT:
Here you can see wich info you can get of a person:
http://developers.facebook.com/docs/reference/login/extended-profile-properties/
And here, wich you can get of a message (user_status):
http://developers.facebook.com/docs/reference/fql/location_post/
after you have this you can pull out the information using:
$config = array(
‘appId’ => FBAPPID,
‘secret’ => FBAPPSECRET,
);
$facebook = new Facebook($config);
$fbuserid = $facebook->getUser();
$params = array(
“scope” => “user_status”,
“redirect_uri” => “http://www.yoursite.com/”
);
$loginurl = $facebook->getLoginUrl($params);
hi all when clicking the link on my page its not carrying the id from the template when going to the view page, so when the sql queries the database it is querying this
SELECT `Field`.`name`
FROM `pra`.`fields` AS `Field`
LEFT JOIN `pra`.`templates` AS `Template` ON (
`Field`.`template_id` = `Template`.`id`)
WHERE `template`.`id` IS NULL
the database says id should be = 2
here is the code for the view function
$fields = $this->Field->find('all',
array('fields'=>array('name','template_id'),
'conditions' => array('template_id' => $this->Auth->user('template.id'))));
$this->set('field', $fields);
updated code, the template_id still equals null
when hardcoded it works correctly, there is a problem with this line $this->Auth->user
You can try with the following code:
$fields = $this->Field->find('all',
array('fields'=>array('name'),
'conditions' => array('Field.template_id' => $this->Auth->user('template_id'))
)
);
$this->set('field', $fields);
Please be sure there must have any template_id value should be there for the current logged in user.
Kindly ask if it not worked for you.
Check the result of the find call, by doing a debug:
debug($fields);
This will show you the returned data from the query. You can add this to the end of your action method.
If the results are empty, double check the values that are stored in the session Auth key. You can do this by dumping out the session with debug($_SESSION) or use the CakePHP DebugKit. The Debug Kit offers you a small toolbar at the top right of the screen and lets you view session information and such.
function view($name){
$this->set('title_for_layout', 'Create Template');
$this->set('stylesheet_used', 'homestyle');
$this->set('image_used', 'eBOXLogoHome.jpg');
$this->layout='home_layout';
$fields = $this->Template->Field->find('list',array(
'fields'=> array('name'),
'conditions' => array(
'template_id'=> $name)));
$this->set('field', $fields);
}
it wasn't passing the param's value
The ORM in FuelPHP has an update example that looks like this:
$entry = Model_Article::find(4);
$entry->title = 'My first edit';
$entry->author = 'Total n00b';
$entry->save();
I'm wondering if there is an ability for me to update w/ something like this:
$values = array(
'this' => $that
);
Model_Article::find(4)->save($values);
The insert ability allows for passing arrays of values:
$props = array('property' => 'something');
$new = Model_Example::forge($props)->save();
But I see no example of doing the same thing w/ the update ability.
EDIT: It appears Model_Example::find(4)->values($array)->save(); is what I'm looking for.
It appears Model_Example::find(4)->values($array)->save(); is what I'm looking for.
I just started learning LINQ2SQL and one of the first things I wanted to try is a simple parent-child hierarchy, but I can't seem to find a good way to do it. I saw some examples here on SO and i've googled, but I couldn't apply them directly, so I'll explain exactly what i'm trying to accomplish.
Lets use the common example with tags.
Database tables: Post-- Post_Tags -- Tags
I've created a simple Post class so I avoid passing Linq2Sql classes around:
public class Post
{
public int Id {get; set;}
public int Title {get; set;}
public IEnumerable<string> Tags {get; set;}
}
I would like to select 5 latest records from the Posts table, get their related tags and return the IList where each Post has their Tags property filled.
Can you show me a concrete Linq2Sql code how could I do that?
I tried:
IList<Post> GetLatest()
{
return (from p in _db.Posts
orderby p.DateCreated descending
select new Post
{
Id = p.Id,
Title = p.Title,
Tags = p.Post_Tags.Select(pt => pt.Tag.Name)
}).Take(5).ToList();
}
This works but duplicates Post records for each Tag record and I have to duplicate property mapping (Id=p.Id, ...) in every method I user. I then tried this approach, but in this case, I have a roundtrip to DB for every tag:
IQueryable<Post> GetList()
{
return (from p in _db.Posts
select new Post
{
Id = p.Id,
Title = p.Title,
Tags = p.Post_Tags.Select(pt => pt.Tag.Name)
});
}
IList<Post> GetLatest()
{
return (from p in GetList()
orderby p.DateCreated descending
select p).Take(5).ToList();
}
If I were doing it in classic ADO.NET, I would create a stored procedure that returns two resultsets. One with Post records and second with related Tag records. I would then map them in the code (by hand, by DataRelation, ORM, etc.). Could I do the same with LINQ2SQL?
I'm really curious to see some code samples on how do you guys handle such simple hierarchies.
And yes, I would really like to return IList<> objects and my custom classes and not queryable Linq to Sql objects, because I would like to be flexible about the data access code if I for example decide to abandon Linq2Sql.
Thanks.
If you create a DataContext, the parent-child relationship is maintained automatically for you.
i.e. If you model the Posts and Tags and their relationship inside a Linq2Sql DataContext, you can then fetch posts like this:
var allPosts = from p in _db.Posts
orderby p.DateCreated descending
select p;
Then you won't have to worry about any tags at all, because they are accessible as a member of the variable p as in:
var allPostsList = allPosts.ToList();
var someTags = allPostsList[0].Post_Tags;
var moreTags = allPostsList[1].Post_Tags;
And then any repeated instance is then automatically updated across entire DataContext until you ask it to SubmitChanges();
IMO, That's the point of an ORM, you don't re-create the model class and maintain the mapping across many places because you want all those relationships managed for you by the ORM.
As for the roundtrip, if you refrain from any code that explicitly requests a trip to the database, all queries will be stored in an intermediate query representation and only when the data is actually needed to continue, is when the query will be translated to sql and dispatched to the database to fetch results.
i.e. the following code only access the database once
// these 3 variables are all in query form until otherwise needed
var allPosts = Posts.All();
var somePosts = allPosts.Where(p => p.Name.Contains("hello"));
var lesserPosts = somePosts.Where(p => p.Name.Contains("World"));
// calling "ToList" will force the query to be sent to the db
var result = lesserPosts.ToList();
How about if you set your DataLoadOptions first to explicitly load tags with posts? Something like:
IList<Post> GetLatest()
{
DataLoadOptions options = new DataLoadOptions();
options.LoadWith<Post>(post => post.Tags);
_db.LoadOptions = options;
return (from p in _db.Posts
orderby p.DateCreated descending)
Take(5).ToList();
}
List<Post> latestPosts = db.Posts
.OrderByDescending( p => p.DateCreated )
.Take(5)
.ToList();
// project the Posts to a List of IDs to send back in
List<int> postIDs = latestPosts
.Select(p => p.Id)
.ToList();
// fetch the strings and the ints used to connect
ILookup<int, string> tagNameLookup = db.Posts
.Where(p => postIDs.Contains(p.Id))
.SelectMany(p => p.Post_Tags)
.Select(pt => new {PostID = pt.PostID, TagName = pt.Tag.Name } )
.ToLookup(x => x.PostID, x => x.TagName);
//now form results
List<Post> results = latestPosts
.Select(p => new Post()
{
Id = p.Id,
Title = p.Title,
Tags = tagNameLookup[p.Id]
})
.ToList();