2016-10-27 3 views
1

タイトルは少し曖昧ですが、私が達成しようとしていることを説明しましょう。小枝の値をループして空の値を置き換えます

Symfony2 CRMの教義クエリから取得したデータに基づいてCSVを生成しようとしています。取得されるデータは、OpenCart製品および属性データ、およびこの問題とは関係のない個別の情報に基づいています。

各製品には、A、B、D、L1、L2という5つの異なる属性値を設定できます。しかし、一部の製品では、A、B、L1のみがすべて含まれているわけではありません。 CSVでは、各属性値を別々のセルに入れる必要があるため、ヘッダーは次のようになります。

属性| ATTRIBUTE:B | ATTRIBUTE:D | ATTRIBUTE:L1 | ATTRIBUTE:L2

そして、私の小枝ファイルに貫通し、私ループは次のように:製品はすべて5つの属性を持っている場合

{% for attribute in row.product.attributes %} 
    {% if attribute.text is not null %} 
     {{ attribute.text }}, 
    {% else %}na,{% endif %} 
{% endfor %} 

は、CSVの構造が細かいです。しかし、製品に3つの属性しかない場合は、後続のすべての値がセルに引き戻され、他のデータが間違った見出しの下にあることを意味します。私は最初の値をチェックしてみました:

{% for attribute in row.product.attributes %} 
    {% if attribute.attributeName.name == "A" %} 
     {% if attribute.text is not null %} 
      {{ attribute.text }}, 
     {% else %}na,{% endif %} 
    {% endif %} 
{% endfor %} 

そして私は、可能な各属性名のためにこれをやったが、名前が存在しない場合、それだけでとにかくそれをスキップするのでunfortuantelyこれは動作しません。私は、これらの属性をループし、存在しない場合はn/aを入力する方法を考えようとするのに問題があります。私は方法があると確信していますが、それは何か分かりません。参考のため

は、ここにCSVのデータを生成するのコントローラーコードです:

public function adminCsvAction($filter) { 

    $repository = $this->getDoctrine()->getRepository('AppBundle:Project'); 
    $stages_repository = $this->getDoctrine()->getRepository('AppBundle:Stage'); 
    $users_repository = $this->getDoctrine()->getRepository('AppBundle:User'); 

    $results = $repository->getSearchResults($filter); 
    $users = $users_repository->findAll(); 
    $stages = $stages_repository->findBy(array('deleted' => 0), array('sortOrder' => 'ASC')); 

    $filename = "export_".date("Y_m_d_His").".csv"; 

    $response = $this->render('AppBundle:pages:csv.html.twig', array('data' => $results,'users' => $users, 'stages' => $stages)); 
    $response->headers->set('Content-Type', 'text/csv'); 

    $response->headers->set('Content-Disposition', 'attachment; filename='.$filename); 
    return $response; 
} 

Projectエンティティは、すべての属性を意味OpenCartのProductテーブルにリンクし、リンクされそのうちの一つ、さまざまなマッピングを、持っています値はこれを介してアクセス可能です。

これについての助力は非常に高く評価されます。

+2

twigでのプログラミング(phpと比較して)が苦しいことがあります。個人的には、製品データを入力として受け入れ、5つのスロットすべてに何かを記入したcsv ready配列を返すPHP関数を記述します。 – Cerad

+1

私はCeradに同意し、プレゼンテーションのために 'twig'を使うべきであり、変更はしません – DarkBee

+0

各変数をvar_dumpingしようとしましたか?私も同様の問題があり、var_dumpedを使って、あなたのケースに翻訳して、 'attribute.text'の代わりに' attribute [0] .text'を使用する必要があることを確認してください。 – Florian

答えて

0

また、私はCeradのコメント欄に同意します。これはTwigの仕事ではありません。場合は、あなたのは本当にそれを実行する必要があり、私は大体このような何かしようとするだろう:

{% set allAttr = ["A","B","D","L1","L2"] %} 

{% for attribute in allAttr %} 
    {% if row.product.attributes[attribute] is defined %} 
     {{ row.product.attributes[attribute].text }} 
    {% endif %} 

    {% if not loop.last %},{% endif %} 
{% endfor %} 

を私はそれを考え出した

+0

これは良い考えですが、 'row.product.attributes属性エンティティ配列内のattributeNameという別のエンティティでA、B、Cなどが参照されるため、[attribute]は存在しません。 –

+0

それで、 '定義されている'が、 'if'が存在しなければそれをスキップします。 –

+0

いいえ、属性名が別のエンティティ内にあるため、決して存在しないということです。基本的には、提案したコードを使用するたびに結果が表示されません(例:na、na、na、na、na)。 row.product.attributesには、配列キーが「A」または「B」でないと仮定しています。 –

0

OK ... is definedがここに重要であると思います。 Jovan Perovicが提案したものを使用して、私はこれを思いつきました:

{% set allAttr = ["A","B","D","L1","L2"] %} 
{% set prodAtts = [] %} 
{% for row in data %} 
    {% set existingAtts = [] %} 
    {% for att in allAttr %} 
     {% if att not in prodAtts %} 
      {% set prodAtts = prodAtts|merge([att]) %} 
     {% endif %} 
    {% endfor %} 
    {% for rowAtt in row.product.attributes %} 
     {% set existingAtts = existingAtts|merge({(rowAtt.attributeName.name|trim):(rowAtt.attributeName.name|trim~'_'~rowAtt.text|trim)}) %} 
    {% endfor %} 
    {% for prodAtt in prodAtts %} 
     {% if prodAtt not in existingAtts|keys %} 
      {% set existingAtts = existingAtts|merge({(prodAtt):(prodAtt~'_na')}) %} 
     {% endif %} 
    {% endfor %} 
     {% set orderedAtts = existingAtts|sort %} 
.... 

その後、各行のループが続きます。私は属性名をアンダースコアで正しく並べ替えることができるように(キーではない値でソートするだけです)、preg_replaceを使用して名前のインスタンスと共に削除しました。

長いと思うかもしれないが、おそらく考えられている解決策のビットですが、機能します!

関連する問題