0

Im using the google map api with a database connection, I have a function that output an xml file and the JavaScript reads the coordinates . no problem there.

Now i want to add another function that prints out the users that have saved coordinates in the db.

But my xml file prints out like this.

<blog title="Ipsum" text="IpsumLorem" lat="31.968599" lng="-99.901810"/>
<blog username="user1"/>

instead of printing user1 in the first row like this

<blog title="Ipsum" text="IpsumLorem" lat="31.968599" lng="-99.901810" username="user1" />

this is my two functions

function fetch_articles() {
    $query = $this->link->query("SELECT * FROM blog ");  
    $query->setFetchMode(PDO::FETCH_ASSOC);
    while($row = $query->fetch()) {  
        $node = $dom->createElement("blog");  
    $newnode = $parnode->appendChild($node);   
    $newnode->setAttribute("title",$row['title']);
    $newnode->setAttribute("text", $row['text']);  
    $newnode->setAttribute("lat", $row['lat']);  
    $newnode->setAttribute("lng", $row['lng']);  
    } 
}

function fetch_users() {
    $query = $this->link->query("SELECT * FROM user ");  
    $query->setFetchMode(PDO::FETCH_ASSOC);
    while($row = $query->fetch()) {  
        $node = $dom->createElement("blog");  
    $newnode = $parnode->appendChild($node);   
    $newnode->setAttribute("username",$row['username']);
    } 
}



 $area = new Areas();
$area_info = $area->fetch_articles(); 
$user_info = $area->fetch_users(); 
echo $dom->saveXML();

Any ideas ?

5
  • 1
    Put the two functions' bodies into one function, then write an SQL query to look up blog entries and associated users, and add them to the same blog DOM element. If you need help with that, just ask. I'd need more information about your actual setup do answer that question in more detail. Commented May 19, 2013 at 15:19
  • In the second function name the element user instead of blog. Commented May 19, 2013 at 15:27
  • @likeitlikeit Something like this ? SELECT blog.title,blog.text,blog.lat,blog.lng, user.username FROM blog JOIN user and the connect it to the user_id ? Commented May 19, 2013 at 15:30
  • @Dymond Exactly! Should I write that into an answer? Commented May 19, 2013 at 15:33
  • @likeitlikeit I just got it to work,! THANK YOU, sometimes you just need a little push! if you write it as an answer ill accept it :) Commented May 19, 2013 at 15:34

2 Answers 2

2

You need to apply the attribute changes on the same DOMElement. Because both methods actually contain quite the same code, it's also worth to encapsulate that as well:

$blog = $dom->createElement("blog");

$apply = new DomAttributeApplyIterator(
    new PdoQueryIterator($pdo, "SELECT * FROM blog"), $blog
);
$apply->apply();

$apply = new DomAttributeApplyIterator(
    new PdoQueryIterator($pdo, "SELECT * FROM user"), $blog
);
$apply->apply();

echo $dom->saveXML();

The two new types used:

class DomAttributeApplyIterator extends IteratorIterator
{
    /**
     * @var DOMElement
     */
    private $element;

    public function __construct(Traversable $iterator, DOMElement $element) {
        parent::__construct($iterator);
        $this->element = $element;
    }

    public function apply() {
        foreach($this as $key => $value) {
            $this->element->setAttribute($key, $value);
        }
    }
}

class PdoQueryIterator implements IteratorAggregate
{
    private $pdo, $query;

    public function __construct(PDO $pdo, $query) {
        $this->pdo = $pdo;
        $this->query = $query;
    }

    public function getIterator() {
        $stmt = $this->pdo->query($this->query);
        $stmt->setFetchMode(PDO::FETCH_ASSOC);
        return $stmt;
    }
}
Sign up to request clarification or add additional context in comments.

8 Comments

That looks interesting, but how does it actually solve the question?
By moving the blog-element creation out of the database query functionality.
really interesting solution, i will def. try it. Thank you @hakre
This is cool! I think the original problem was that there was a JOIN missing in the original version, as the results from the blog table and the users table don't match up. Food for though for me, though...
Start by looking at the duplicate code inside your two functions. Consider how to move that into a central place.
|
1

The code you have lacks a way of connecting the users with the blog posts. Thus, it's probably easiest to just write a query that fetches both in a single result, then adds that to a DOM node. It could work like this:

function fetch_articles_with_username() {
    $query = $this->link->query("SELECT * FROM blog LEFT JOIN user WHERE blog.userid = user.id ");  
    $query->setFetchMode(PDO::FETCH_ASSOC);
    while($row = $query->fetch()) {  
        $node = $dom->createElement("blog");  
        $newnode = $parnode->appendChild($node);   
        $newnode->setAttribute("title",$row['title']);
        $newnode->setAttribute("text", $row['text']);  
        $newnode->setAttribute("lat", $row['lat']);  
        $newnode->setAttribute("lng", $row['lng']);  
        $newnode->setAttribute("username",$row['username']);
    } 
}

You'd use it like above, just making a single call to fetch_articles_with_username().

6 Comments

You have an undefined variable $dom inside your method - it does fatal-error on $dom->createElement("blog");.
@hakre Saw it tool. It's probably a global variable, I took it straight out of the asker's post.
Yes friends, its global variables, haven't found out how to solve that yet :)
@Dymond: You need to inject it. Don't fall into the global trap. You can also make it return a new domelement that you then import into a document later. Then you don't need $dom at all and only the name of the element is hardcoded.
@Dymond: Actually I think the root-problem is located elsewhere: You have written the method without returning a value. So you have interdirect returns here. This is a sign you should only modify private members (internal state of the object). That also moves the global away (because it's a private member). And then all you need is a getter/setter pair to set the document object and the element name. But still I'd say this is doing too much :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.